blob: a2b59244ab85cc359606ec98698456eb563cd761 [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
Zack Williams9a42f872019-02-15 17:56:04 -070016from __future__ import absolute_import
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040017import unittest
Scott Baker1f7791d2018-10-04 13:21:20 -070018from xosgenx.generator import XOSProcessor, XOSProcessorArgs
19from helpers import XProtoTestHelpers, FakeObject
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040020import pdb
21
22"""The function below is for eliminating warnings arising due to the missing policy_output_validator,
23which is generated and loaded dynamically.
24"""
Zack Williams045b63d2019-01-22 16:30:57 -070025
26
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040027def policy_output_validator(x, y):
28 raise Exception("Validator not generated. Test failed.")
29 return False
30
Zack Williams045b63d2019-01-22 16:30:57 -070031
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040032"""
Zack Williams045b63d2019-01-22 16:30:57 -070033The tests below use the Python code target to generate
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040034Python validation policies, set up an appropriate environment and execute the Python.
35"""
Zack Williams045b63d2019-01-22 16:30:57 -070036
37
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040038class XProtoGeneralValidationTest(unittest.TestCase):
39 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070040 self.target = XProtoTestHelpers.write_tmp_target(
41 """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040042{% for name, policy in proto.policies.items() %}
43{{ xproto_fol_to_python_validator(name, policy, None, 'Necessary Failure') }}
44{% endfor %}
Zack Williams045b63d2019-01-22 16:30:57 -070045"""
46 )
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040047
48 def test_constant(self):
Zack Williams045b63d2019-01-22 16:30:57 -070049 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040050 policy output < False >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040051"""
Zack Williams045b63d2019-01-22 16:30:57 -070052 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040053
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080054 output = XOSProcessor.process(args)
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 i1 = False
61 if (not i1):
62 raise Exception('Necessary Failure')
63 """
64
65 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070066 policy_output_validator({}, {})
67
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040068 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070069 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040070 policy output < not (ctx.user = obj.user) >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040071"""
72
Zack Williams045b63d2019-01-22 16:30:57 -070073 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040074
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080075 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040076
Zack Williams045b63d2019-01-22 16:30:57 -070077 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040078
79 """
80 def policy_output_validator(obj, ctx):
81 i2 = (ctx.user == obj.user)
82 i1 = (not i2)
83 if (not i1):
84 raise Exception('Necessary Failure')
85 """
86
Scott Baker1f7791d2018-10-04 13:21:20 -070087 obj = FakeObject()
88 obj.user = 1
89 ctx = FakeObject()
90 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040091
92 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070093 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040094
95 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070096 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040097 policy output < not (ctx.user = obj.user) >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040098"""
99
Zack Williams045b63d2019-01-22 16:30:57 -0700100 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400101
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800102 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400103
Zack Williams045b63d2019-01-22 16:30:57 -0700104 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400105
106 """
107 def policy_output_validator(obj, ctx):
108 i2 = (ctx.user == obj.user)
109 i1 = (not i2)
110 if (not i1):
111 raise Exception('Necessary Failure')
112 """
113
Scott Baker1f7791d2018-10-04 13:21:20 -0700114 obj = FakeObject()
115 obj.user = 1
116 ctx = FakeObject()
117 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400118
119 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -0700120 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400121
122 def test_bin(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700123 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400124 policy output < (ctx.is_admin = True | obj.empty = True) | False>
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400125"""
126
Scott Baker1f7791d2018-10-04 13:21:20 -0700127 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400128 args.inputs = xproto
129 args.target = self.target
130
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800131 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700132 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400133
134 """
135 def policy_output_validator(obj, ctx):
136 i2 = (ctx.is_admin == True)
137 i3 = (obj.empty == True)
138 i1 = (i2 or i3)
139 if (not i1):
140 raise Exception('Necessary Failure')
141 """
142
Scott Baker1f7791d2018-10-04 13:21:20 -0700143 obj = FakeObject()
144 obj.empty = False
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400145
Scott Baker1f7791d2018-10-04 13:21:20 -0700146 ctx = FakeObject()
147 ctx.is_admin = False
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400148
149 with self.assertRaises(Exception):
150 verdict = policy_output_validator(obj, ctx)
151
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400152 def test_exists(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700153 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400154 policy output < exists Privilege: Privilege.object_id = obj.id >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400155"""
Zack Williams045b63d2019-01-22 16:30:57 -0700156 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400157
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800158 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700159 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400160
161 """
162 def policy_output_validator(obj, ctx):
163 i1 = Privilege.objects.filter(Q(object_id=obj.id))[0]
164 if (not i1):
165 raise Exception('Necessary Failure')
166 """
167
168 self.assertTrue(policy_output_validator is not None)
Zack Williams045b63d2019-01-22 16:30:57 -0700169
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400170 def test_python(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700171 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400172 policy output < {{ "jack" in ["the", "box"] }} = True >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400173"""
Zack Williams045b63d2019-01-22 16:30:57 -0700174 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800175 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700176 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400177
178 """
179 def policy_output_validator(obj, ctx):
180 i2 = ('jack' in ['the', 'box'])
181 i1 = (i2 == True)
182 if (not i1):
183 raise Exception('Necessary Failure')
184 """
185
186 with self.assertRaises(Exception):
187 self.assertTrue(policy_output_validator({}, {}) is True)
188
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400189 def test_call_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700190 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400191 policy sub_policy < ctx.user = obj.user >
192 policy output < *sub_policy(child) >
193"""
194
Zack Williams045b63d2019-01-22 16:30:57 -0700195 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400196
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800197 output = XOSProcessor.process(args)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400198
Zack Williams045b63d2019-01-22 16:30:57 -0700199 exec(
200 output, globals()
201 ) # This loads the generated function, which should look like this:
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400202
203 """
204 def policy_sub_policy_validator(obj, ctx):
205 i1 = (ctx.user == obj.user)
206 if (not i1):
207 raise ValidationError('Necessary Failure')
208
209 def policy_output_validator(obj, ctx):
210 i1 = policy_sub_policy_validator(obj.child, ctx)
211 if (not i1):
212 raise ValidationError('Necessary Failure')
213 """
214
Scott Baker1f7791d2018-10-04 13:21:20 -0700215 obj = FakeObject()
216 obj.child = FakeObject()
217 obj.child.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400218
Scott Baker1f7791d2018-10-04 13:21:20 -0700219 ctx = FakeObject()
220 ctx.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400221
222 with self.assertRaises(Exception):
223 verdict = policy_output_enforcer(obj, ctx)
224
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400225 def test_forall(self):
226 # This one we only parse
Zack Williams045b63d2019-01-22 16:30:57 -0700227 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400228 policy output < forall Credential: Credential.obj_id = obj_id >
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400229"""
230
Zack Williams045b63d2019-01-22 16:30:57 -0700231 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400232
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800233 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400234
235 """
236 def policy_output_enforcer(obj, ctx):
237 i2 = Credential.objects.filter((~ Q(obj_id=obj_id)))[0]
238 i1 = (not i2)
239 return i1
240 """
241
Zack Williams045b63d2019-01-22 16:30:57 -0700242 self.assertIn("policy_output_validator", output)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400243
Zack Williams045b63d2019-01-22 16:30:57 -0700244
245if __name__ == "__main__":
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400246 unittest.main()