blob: 0e2a7858a6c7aacb64eddd0f82918e1bf4c5d1ee [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 XProtoTestHelpers, FakeObject
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040019import pdb
20
21"""The function below is for eliminating warnings arising due to the missing policy_output_validator,
22which is generated and loaded dynamically.
23"""
Zack Williams045b63d2019-01-22 16:30:57 -070024
25
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040026def policy_output_validator(x, y):
27 raise Exception("Validator not generated. Test failed.")
28 return False
29
Zack Williams045b63d2019-01-22 16:30:57 -070030
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040031"""
Zack Williams045b63d2019-01-22 16:30:57 -070032The tests below use the Python code target to generate
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040033Python validation policies, set up an appropriate environment and execute the Python.
34"""
Zack Williams045b63d2019-01-22 16:30:57 -070035
36
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040037class XProtoGeneralValidationTest(unittest.TestCase):
38 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070039 self.target = XProtoTestHelpers.write_tmp_target(
40 """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040041{% for name, policy in proto.policies.items() %}
42{{ xproto_fol_to_python_validator(name, policy, None, 'Necessary Failure') }}
43{% endfor %}
Zack Williams045b63d2019-01-22 16:30:57 -070044"""
45 )
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040046
47 def test_constant(self):
Zack Williams045b63d2019-01-22 16:30:57 -070048 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040049 policy output < False >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040050"""
Zack Williams045b63d2019-01-22 16:30:57 -070051 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040052
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080053 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040054
Zack Williams045b63d2019-01-22 16:30:57 -070055 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040056
57 """
58 def policy_output_validator(obj, ctx):
59 i1 = False
60 if (not i1):
61 raise Exception('Necessary Failure')
62 """
63
64 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070065 policy_output_validator({}, {})
66
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040067 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070068 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040069 policy output < not (ctx.user = obj.user) >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040070"""
71
Zack Williams045b63d2019-01-22 16:30:57 -070072 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040073
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080074 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040075
Zack Williams045b63d2019-01-22 16:30:57 -070076 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040077
78 """
79 def policy_output_validator(obj, ctx):
80 i2 = (ctx.user == obj.user)
81 i1 = (not i2)
82 if (not i1):
83 raise Exception('Necessary Failure')
84 """
85
Scott Baker1f7791d2018-10-04 13:21:20 -070086 obj = FakeObject()
87 obj.user = 1
88 ctx = FakeObject()
89 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040090
91 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070092 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040093
94 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070095 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040096 policy output < not (ctx.user = obj.user) >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040097"""
98
Zack Williams045b63d2019-01-22 16:30:57 -070099 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400100
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800101 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400102
Zack Williams045b63d2019-01-22 16:30:57 -0700103 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400104
105 """
106 def policy_output_validator(obj, ctx):
107 i2 = (ctx.user == obj.user)
108 i1 = (not i2)
109 if (not i1):
110 raise Exception('Necessary Failure')
111 """
112
Scott Baker1f7791d2018-10-04 13:21:20 -0700113 obj = FakeObject()
114 obj.user = 1
115 ctx = FakeObject()
116 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400117
118 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -0700119 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400120
121 def test_bin(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700122 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400123 policy output < (ctx.is_admin = True | obj.empty = True) | False>
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400124"""
125
Scott Baker1f7791d2018-10-04 13:21:20 -0700126 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400127 args.inputs = xproto
128 args.target = self.target
129
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800130 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700131 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400132
133 """
134 def policy_output_validator(obj, ctx):
135 i2 = (ctx.is_admin == True)
136 i3 = (obj.empty == True)
137 i1 = (i2 or i3)
138 if (not i1):
139 raise Exception('Necessary Failure')
140 """
141
Scott Baker1f7791d2018-10-04 13:21:20 -0700142 obj = FakeObject()
143 obj.empty = False
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400144
Scott Baker1f7791d2018-10-04 13:21:20 -0700145 ctx = FakeObject()
146 ctx.is_admin = False
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400147
148 with self.assertRaises(Exception):
149 verdict = policy_output_validator(obj, ctx)
150
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400151 def test_exists(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700152 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400153 policy output < exists Privilege: Privilege.object_id = obj.id >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400154"""
Zack Williams045b63d2019-01-22 16:30:57 -0700155 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400156
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800157 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700158 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400159
160 """
161 def policy_output_validator(obj, ctx):
162 i1 = Privilege.objects.filter(Q(object_id=obj.id))[0]
163 if (not i1):
164 raise Exception('Necessary Failure')
165 """
166
167 self.assertTrue(policy_output_validator is not None)
Zack Williams045b63d2019-01-22 16:30:57 -0700168
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400169 def test_python(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700170 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400171 policy output < {{ "jack" in ["the", "box"] }} = True >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400172"""
Zack Williams045b63d2019-01-22 16:30:57 -0700173 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800174 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700175 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400176
177 """
178 def policy_output_validator(obj, ctx):
179 i2 = ('jack' in ['the', 'box'])
180 i1 = (i2 == True)
181 if (not i1):
182 raise Exception('Necessary Failure')
183 """
184
185 with self.assertRaises(Exception):
186 self.assertTrue(policy_output_validator({}, {}) is True)
187
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400188 def test_call_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700189 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400190 policy sub_policy < ctx.user = obj.user >
191 policy output < *sub_policy(child) >
192"""
193
Zack Williams045b63d2019-01-22 16:30:57 -0700194 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400195
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800196 output = XOSProcessor.process(args)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400197
Zack Williams045b63d2019-01-22 16:30:57 -0700198 exec(
199 output, globals()
200 ) # This loads the generated function, which should look like this:
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400201
202 """
203 def policy_sub_policy_validator(obj, ctx):
204 i1 = (ctx.user == obj.user)
205 if (not i1):
206 raise ValidationError('Necessary Failure')
207
208 def policy_output_validator(obj, ctx):
209 i1 = policy_sub_policy_validator(obj.child, ctx)
210 if (not i1):
211 raise ValidationError('Necessary Failure')
212 """
213
Scott Baker1f7791d2018-10-04 13:21:20 -0700214 obj = FakeObject()
215 obj.child = FakeObject()
216 obj.child.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400217
Scott Baker1f7791d2018-10-04 13:21:20 -0700218 ctx = FakeObject()
219 ctx.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400220
221 with self.assertRaises(Exception):
222 verdict = policy_output_enforcer(obj, ctx)
223
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400224 def test_forall(self):
225 # This one we only parse
Zack Williams045b63d2019-01-22 16:30:57 -0700226 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400227 policy output < forall Credential: Credential.obj_id = obj_id >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400228"""
229
Zack Williams045b63d2019-01-22 16:30:57 -0700230 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400231
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800232 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400233
234 """
235 def policy_output_enforcer(obj, ctx):
236 i2 = Credential.objects.filter((~ Q(obj_id=obj_id)))[0]
237 i1 = (not i2)
238 return i1
239 """
240
Zack Williams045b63d2019-01-22 16:30:57 -0700241 self.assertIn("policy_output_validator", output)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400242
Zack Williams045b63d2019-01-22 16:30:57 -0700243
244if __name__ == "__main__":
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400245 unittest.main()