blob: 65555a306949f0ee4840115453c9faa75e551e16 [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
Zack Williams9a42f872019-02-15 17:56:04 -070015from __future__ import absolute_import
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
Zack Williams045b63d2019-01-22 16:30:57 -070020
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040021def policy_output_validator(x, y):
Zack Williams9a42f872019-02-15 17:56:04 -070022 """
23 For eliminating warnings arising due to the missing
24 policy_output_validator, which is generated and loaded dynamically.
25 """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040026 raise Exception("Validator not generated. Test failed.")
27 return False
28
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040029class XProtoXOSModelValidationTest(unittest.TestCase):
Zack Williams9a42f872019-02-15 17:56:04 -070030 """
31 Use the Python code target to generate Python validation policies, set up an
32 appropriate environment and execute the Python.
33 """
34
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040035 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070036 self.target = XProtoTestHelpers.write_tmp_target(
37 "{{ xproto_fol_to_python_validator('output', proto.policies.test_policy, None, 'Necessary Failure') }}"
38 )
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040039
40 def test_instance_container(self):
Zack Williams045b63d2019-01-22 16:30:57 -070041 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040042 policy test_policy < (obj.isolation = "container" | obj.isolation = "container_vm" ) -> (obj.image.kind = "container") >
43"""
Scott Baker1f7791d2018-10-04 13:21:20 -070044 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040045 args.inputs = xproto
46 args.target = self.target
47
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080048 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040049
Scott Baker1f7791d2018-10-04 13:21:20 -070050 obj = FakeObject()
Zack Williams045b63d2019-01-22 16:30:57 -070051 obj.isolation = "container"
52 obj.kind = "not a container"
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040053
Zack Williams045b63d2019-01-22 16:30:57 -070054 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040055
56 """
57 def policy_output_validator(obj, ctx):
58 i4 = (obj.isolation == 'container')
59 i5 = (self.isolation == 'container_vm')
60 i2 = (i4 or i5)
61 i3 = (obj.image.kind == 'container')
62 i1 = (i2 or i3)
63 return i1
64 """
65
66 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070067 policy_output_validator(obj, {})
68
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040069 def test_slice_name_validation(self):
Zack Williams045b63d2019-01-22 16:30:57 -070070 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040071 policy test_policy < not obj.id -> {{ obj.name.startswith(obj.site.login_base) }} >
72"""
Scott Baker1f7791d2018-10-04 13:21:20 -070073 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040074 args.inputs = xproto
75 args.target = self.target
76
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080077 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040078
Scott Baker1f7791d2018-10-04 13:21:20 -070079 obj = FakeObject()
Zack Williams045b63d2019-01-22 16:30:57 -070080 obj.isolation = "container"
81 obj.kind = "not a container"
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040082
Zack Williams045b63d2019-01-22 16:30:57 -070083 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040084
85 """
86 def policy_output_validator(obj, ctx):
87 i3 = obj.id
88 i4 = obj.name.startswith(obj.site.login_base)
89 i2 = ((not i3) or i4)
90 i1 = (not i2)
91 if (not i1):
92 raise ValidationError('Necessary Failure')
93 """
94
95 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070096 policy_output_validator(obj, {})
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040097
98 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070099 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400100 policy test_policy < not (ctx.user = obj.user) >
101"""
102
Scott Baker1f7791d2018-10-04 13:21:20 -0700103 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400104 args.inputs = xproto
105 args.target = self.target
106
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800107 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400108
Zack Williams045b63d2019-01-22 16:30:57 -0700109 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400110
111 """
112 def policy_output_validator(obj, ctx):
113 i2 = (ctx.user == obj.user)
114 i1 = (not i2)
115 if (not i1):
116 raise Exception('Necessary Failure')
117 """
118
Scott Baker1f7791d2018-10-04 13:21:20 -0700119 obj = FakeObject()
120 obj.user = 1
121 ctx = FakeObject()
122 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400123
124 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -0700125 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400126
127 def test_bin(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700128 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400129 policy test_policy < not (ctx.is_admin = True | obj.empty = True) | False>
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400130"""
131
Scott Baker1f7791d2018-10-04 13:21:20 -0700132 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400133 args.inputs = xproto
134 args.target = self.target
135
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800136 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700137 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400138
139 """
140 def policy_output_validator(obj, ctx):
141 i2 = (ctx.is_admin == True)
142 i3 = (obj.empty == True)
143 i1 = (i2 or i3)
144 if (not i1):
145 raise Exception('Necessary Failure')
146 """
147
Scott Baker1f7791d2018-10-04 13:21:20 -0700148 obj = FakeObject()
149 obj.empty = True
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400150
Scott Baker1f7791d2018-10-04 13:21:20 -0700151 ctx = FakeObject()
152 ctx.is_admin = True
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400153
154 with self.assertRaises(Exception):
155 verdict = policy_output_validator(obj, ctx)
156
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400157 def test_exists(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700158 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400159 policy test_policy < exists Privilege: Privilege.object_id = obj.id >
160"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700161 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400162 args.inputs = xproto
163 args.target = self.target
164
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800165 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700166 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400167
168 """
169 def policy_output_validator(obj, ctx):
170 i1 = Privilege.objects.filter(Q(object_id=obj.id))[0]
171 if (not i1):
172 raise Exception('Necessary Failure')
173 """
174
175 self.assertTrue(policy_output_validator is not None)
Zack Williams045b63d2019-01-22 16:30:57 -0700176
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400177 def test_python(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700178 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400179 policy test_policy < {{ "jack" in ["the", "box"] }} = True >
180"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700181 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400182 args.inputs = xproto
183 args.target = self.target
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800184 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700185 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400186
187 """
188 def policy_output_validator(obj, ctx):
189 i2 = ('jack' in ['the', 'box'])
190 i1 = (i2 == True)
191 if (not i1):
192 raise Exception('Necessary Failure')
193 """
194
195 with self.assertRaises(Exception):
196 self.assertTrue(policy_output_validator({}, {}) is True)
197
198 def test_forall(self):
199 # This one we only parse
Zack Williams045b63d2019-01-22 16:30:57 -0700200 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400201 policy test_policy < forall Credential: Credential.obj_id = obj_id >
202"""
203
Scott Baker1f7791d2018-10-04 13:21:20 -0700204 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400205 args.inputs = xproto
206 args.target = self.target
207
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800208 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400209
210 """
211 def policy_output_enforcer(obj, ctx):
212 i2 = Credential.objects.filter((~ Q(obj_id=obj_id)))[0]
213 i1 = (not i2)
214 return i1
215 """
216
Zack Williams045b63d2019-01-22 16:30:57 -0700217 self.assertIn("policy_output_validator", output)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400218
Zack Williams045b63d2019-01-22 16:30:57 -0700219
220if __name__ == "__main__":
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400221 unittest.main()