blob: c675b16256e78601094f1095d7868ac309fd7b21 [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 Bhatia3e3c1cd2017-07-15 01:35:44 -040016import unittest
Scott Baker1f7791d2018-10-04 13:21:20 -070017from xosgenx.generator import XOSProcessor, XOSProcessorArgs
18from helpers import XProtoTestHelpers, FakeObject
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040019
Sapan Bhatiae294aae2017-09-06 11:21:15 -040020"""The function below is for eliminating warnings arising due to the missing output_security_check,
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040021which is generated and loaded dynamically.
22"""
Zack Williams045b63d2019-01-22 16:30:57 -070023
24
Sapan Bhatiae294aae2017-09-06 11:21:15 -040025def output_security_check(x, y):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040026 raise Exception("Security enforcer not generated. Test failed.")
27 return False
28
Zack Williams045b63d2019-01-22 16:30:57 -070029
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040030"""
Zack Williams045b63d2019-01-22 16:30:57 -070031The tests below use the Python code target to generate
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040032Python security policies, set up an appropriate environment and execute the Python.
33"""
Zack Williams045b63d2019-01-22 16:30:57 -070034
35
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040036class XProtoSecurityTest(unittest.TestCase):
37 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070038 self.target = XProtoTestHelpers.write_tmp_target(
39 """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040040{% for name, policy in proto.policies.items() %}
41{{ xproto_fol_to_python_test(name, policy, None, '0') }}
42{% endfor %}
Zack Williams045b63d2019-01-22 16:30:57 -070043"""
44 )
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040045
46 def test_constant(self):
Zack Williams045b63d2019-01-22 16:30:57 -070047 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040048 policy output < True >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040049"""
Zack Williams045b63d2019-01-22 16:30:57 -070050 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040051
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080052 output = XOSProcessor.process(args)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040053
Zack Williams045b63d2019-01-22 16:30:57 -070054 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040055
56 """
Sapan Bhatiae294aae2017-09-06 11:21:15 -040057 def output_security_check(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040058 i1 = True
59 return i1
60 """
61
Sapan Bhatiae294aae2017-09-06 11:21:15 -040062 verdict = output_security_check({}, {})
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040063 self.assertTrue(verdict)
64
65 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -070066 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040067 policy output < ctx.user = obj.user >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040068"""
69
Zack Williams045b63d2019-01-22 16:30:57 -070070 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040071
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080072 output = XOSProcessor.process(args)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040073
Zack Williams045b63d2019-01-22 16:30:57 -070074 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040075
76 """
Sapan Bhatiae294aae2017-09-06 11:21:15 -040077 def output_security_check(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040078 i1 = (ctx.user == obj.user)
79 return i1
80 """
81
Scott Baker1f7791d2018-10-04 13:21:20 -070082 obj = FakeObject()
83 obj.user = 1
84 ctx = FakeObject()
85 ctx.user = 1
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040086
Sapan Bhatiae294aae2017-09-06 11:21:15 -040087 verdict = output_security_check(obj, ctx)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040088
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040089 def test_call_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -070090 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040091 policy sub_policy < ctx.user = obj.user >
92 policy output < *sub_policy(child) >
93"""
94
Zack Williams045b63d2019-01-22 16:30:57 -070095 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040096
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080097 output = XOSProcessor.process(args)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -040098
Zack Williams045b63d2019-01-22 16:30:57 -070099 exec(
100 output, globals()
101 ) # This loads the generated function, which should look like this:
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400102
103 """
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400104 def sub_policy_security_check(obj, ctx):
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400105 i1 = (ctx.user == obj.user)
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400106 return i1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400107
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400108 def output_security_check(obj, ctx):
109 if obj.child:
Zack Williams045b63d2019-01-22 16:30:57 -0700110 i1 = sub_policy_security_check(obj.child, ctx)
111 else:
112 i1 = True
113 return i1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400114 """
115
Scott Baker1f7791d2018-10-04 13:21:20 -0700116 obj = FakeObject()
117 obj.child = FakeObject()
118 obj.child.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400119
Scott Baker1f7791d2018-10-04 13:21:20 -0700120 ctx = FakeObject()
121 ctx.user = 1
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400122
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400123 verdict = output_security_check(obj, ctx)
124 self.assertTrue(verdict)
125
126 def test_call_policy_child_none(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700127 xproto = """
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400128 policy sub_policy < ctx.user = obj.user >
129 policy output < *sub_policy(child) >
130"""
131
Zack Williams045b63d2019-01-22 16:30:57 -0700132 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400133
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800134 output = XOSProcessor.process(args)
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400135
Zack Williams045b63d2019-01-22 16:30:57 -0700136 exec(
137 output, globals()
138 ) # This loads the generated function, which should look like this:
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400139
140 """
141 def sub_policy_security_check(obj, ctx):
142 i1 = (ctx.user == obj.user)
143 return i1
144
145 def output_security_check(obj, ctx):
146 if obj.child:
Zack Williams045b63d2019-01-22 16:30:57 -0700147 i1 = sub_policy_security_check(obj.child, ctx)
148 else:
149 i1 = True
150 return i1
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400151 """
152
Scott Baker1f7791d2018-10-04 13:21:20 -0700153 obj = FakeObject()
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400154 obj.child = None
155
Scott Baker1f7791d2018-10-04 13:21:20 -0700156 ctx = FakeObject()
157 ctx.user = 1
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400158
Sapan Bhatiac6543dd2017-12-07 11:40:36 -0500159 verdict = output_security_check(obj, ctx)
160 self.assertTrue(verdict)
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400161
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400162 def test_bin(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700163 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400164 policy output < ctx.is_admin = True | obj.empty = True>
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400165"""
166
Zack Williams045b63d2019-01-22 16:30:57 -0700167 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400168
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800169 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700170 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400171
172 """
Zack Williams045b63d2019-01-22 16:30:57 -0700173 def output_security_check(obj, ctx):
174 i2 = (ctx.is_admin == True)
175 i3 = (obj.empty == True)
176 i1 = (i2 or i3)
177 return i1
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400178 """
179
Scott Baker1f7791d2018-10-04 13:21:20 -0700180 obj = FakeObject()
181 obj.empty = True
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400182
Scott Baker1f7791d2018-10-04 13:21:20 -0700183 ctx = FakeObject()
184 ctx.is_admin = True
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400185
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400186 verdict = output_security_check(obj, ctx)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400187
188 self.assertTrue(verdict)
189
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400190 def test_exists(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700191 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400192 policy output < exists Privilege: Privilege.object_id = obj.id >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400193"""
Zack Williams045b63d2019-01-22 16:30:57 -0700194 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400195
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800196 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700197 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400198
199 """
Zack Williams045b63d2019-01-22 16:30:57 -0700200 def output_security_check(obj, ctx):
201 i1 = Privilege.objects.filter(object_id=obj.id)
202 return i1
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400203 """
204
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400205 self.assertTrue(output_security_check is not None)
Zack Williams045b63d2019-01-22 16:30:57 -0700206
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400207 def test_python(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700208 xproto = """
Sapan Bhatiad3fcb662017-07-25 21:13:48 -0400209 policy output < {{ "jack" in ["the", "box"] }} = False >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400210"""
Zack Williams045b63d2019-01-22 16:30:57 -0700211 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800212 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700213 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400214
215 """
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400216 def output_security_check(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400217 i2 = ('jack' in ['the', 'box'])
218 i1 = (i2 == False)
219 return i1
220 """
221
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400222 self.assertTrue(output_security_check({}, {}) is True)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400223
224 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 Bhatia3e3c1cd2017-07-15 01:35:44 -0400228"""
229
Zack Williams045b63d2019-01-22 16:30:57 -0700230 args = XOSProcessorArgs(inputs=xproto, target=self.target)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400231
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800232 output = XOSProcessor.process(args)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400233 """
Sapan Bhatiae294aae2017-09-06 11:21:15 -0400234 def output_security_check(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400235 i2 = Credential.objects.filter((~ Q(obj_id=obj_id)))[0]
236 i1 = (not i2)
237 return i1
238 """
239 exec(output)
240
Zack Williams045b63d2019-01-22 16:30:57 -0700241
242if __name__ == "__main__":
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400243 unittest.main()