blob: b75f3c78677e523b76b7d0daf0fb7a98b576ae49 [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 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
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040019
Zack Williams045b63d2019-01-22 16:30:57 -070020
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040021def policy_output_enforcer(x, y):
Zack Williams9a42f872019-02-15 17:56:04 -070022 """
23 eliminating warnings arising due to the missing policy_output_enforcer,
24 which is generated and loaded dynamically.
25 """
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
Zack Williams045b63d2019-01-22 16:30:57 -070030
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040031class XProtoXOSSecurityTest(unittest.TestCase):
Zack Williams9a42f872019-02-15 17:56:04 -070032 """
33 Use the Python code target to generate Python security policies, set up an
34 appropriate environment and execute the Python. The security policies here
35 deliberately made complex in order to stress the processor.
36 """
37
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040038 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070039 self.target = XProtoTestHelpers.write_tmp_target(
40 "{{ xproto_fol_to_python_test('output',proto.policies.test_policy, None, '0') }}"
41 )
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040042
43 """
44 This is the security policy for controllers
45 """
Zack Williams045b63d2019-01-22 16:30:57 -070046
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040047 def test_controller_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -070048 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -040049 policy test_policy < ctx.user.is_admin | exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.object_type = "Deployment" & Privilege.permission = "role:admin" & Privilege.object_id = obj.id >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040050"""
Scott Baker1f7791d2018-10-04 13:21:20 -070051 args = XOSProcessorArgs()
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040052 args.inputs = xproto
53 args.target = self.target
54
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080055 output = XOSProcessor.process(args)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040056
Zack Williams045b63d2019-01-22 16:30:57 -070057 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040058
59 """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040060 def policy_output_enforcer(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040061 i2 = ctx.user.is_admin
Sapan Bhatiab69f4702017-07-31 16:03:33 -040062 i3 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(object_type='Deployment'), Q(permission='role:admin'), Q(object_id=obj.id))[0]
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040063 i1 = (i2 or i3)
Sapan Bhatiab69f4702017-07-31 16:03:33 -040064 return i1
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040065 """
66
67 # FIXME: Test this policy by executing it
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040068 self.assertTrue(policy_output_enforcer is not None)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040069
70 """
Sapan Bhatiab69f4702017-07-31 16:03:33 -040071 This is the security policy for ControllerNetworks
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -040072 """
Zack Williams045b63d2019-01-22 16:30:57 -070073
Sapan Bhatiab69f4702017-07-31 16:03:33 -040074 def test_controller_network_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -070075 xproto = """
76 policy test_policy <
Sapan Bhatiab69f4702017-07-31 16:03:33 -040077 ctx.user.is_admin
78 | (exists Privilege:
79 Privilege.accessor_id = ctx.user.id
80 & Privilege.accessor_type = "User"
81 & Privilege.object_type = "Slice"
82 & Privilege.object_id = obj.owner.id)
83 | (exists Privilege:
84 Privilege.accessor_id = ctx.user.id
85 & Privilege.accessor_type = "User"
86 & Privilege.object_type = "Site"
87 & Privilege.object_id = obj.owner.site.id
88 & Privilege.permission = "role:admin") >
89"""
Scott Baker1f7791d2018-10-04 13:21:20 -070090 args = XOSProcessorArgs()
Sapan Bhatiab69f4702017-07-31 16:03:33 -040091 args.inputs = xproto
92 args.target = self.target
93
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080094 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -070095 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatiab69f4702017-07-31 16:03:33 -040096
97 """
98 def policy_output_enforcer(obj, ctx):
99 i2 = ctx.user.is_admin
100 i4 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.owner.id))[0]
101 i5 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Site'), Q(object_id=obj.owner.site.id), Q(permission='role:admin'))[0]
102 i3 = (i4 or i5)
103 i1 = (i2 or i3)
104 return i1
105 """
106
107 # FIXME: Test this policy by executing it
108 self.assertTrue(policy_output_enforcer is not None)
109
110 """
111 This is the security policy for Slices
112 """
Zack Williams045b63d2019-01-22 16:30:57 -0700113
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400114 def test_slice_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700115 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400116 policy site_policy <
117 ctx.user.is_admin
118 | (ctx.write_access -> exists Privilege: Privilege.object_type = "Site" & Privilege.object_id = obj.id & Privilege.accessor_id = ctx.user.id & Privilege.permission_id = "role:admin") >
119
120 policy test_policy <
121 ctx.user.is_admin
122 | (*site_policy(site)
123 & ((exists Privilege:
124 Privilege.accessor_id = ctx.user.id
125 & Privilege.accessor_type = "User"
126 & Privilege.object_type = "Slice"
127 & Privilege.object_id = obj.id
128 & (ctx.write_access->Privilege.permission="role:admin"))
129 | (exists Privilege:
130 Privilege.accessor_id = ctx.user.id
131 & Privilege.accessor_type = "User"
132 & Privilege.object_type = "Site"
133 & Privilege.object_id = obj.site.id
134 & Privilege.permission = "role:admin"))
135 )>
Zack Williams045b63d2019-01-22 16:30:57 -0700136
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400137"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700138 args = XOSProcessorArgs()
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400139 args.inputs = xproto
140 args.target = self.target
141
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800142 output = XOSProcessor.process(args)
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400143
Zack Williams045b63d2019-01-22 16:30:57 -0700144 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400145
146 """
147 def policy_output_enforcer(obj, ctx):
Zack Williams045b63d2019-01-22 16:30:57 -0700148 i2 = ctx.user.is_admin
149 i4 = policy_site_policy_enforcer(obj.site, ctx)
150 i10 = ctx.write_access
151 i11 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id), Q(permission='role:admin'))))
152 i8 = (i10 and i11)
153 i14 = ctx.write_access
154 i12 = (not i14)
155 i13 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id))))
156 i9 = (i12 and i13)
157 i6 = (i8 or i9)
158 i7 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Site'), Q(object_id=obj.site.id), Q(permission='role:admin'))))
159 i5 = (i6 or i7)
160 i3 = (i4 and i5)
161 i1 = (i2 or i3)
162 return i1
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400163 """
164
165 # FIXME: Test this policy by executing it
166 self.assertTrue(policy_output_enforcer is not None)
167
168 """
169 This is the security policy for Users
170 """
Zack Williams045b63d2019-01-22 16:30:57 -0700171
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400172 def test_user_policy(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700173 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400174 policy test_policy <
175 ctx.user.is_admin
176 | ctx.user.id = obj.id
Zack Williams045b63d2019-01-22 16:30:57 -0700177 | (exists Privilege:
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400178 Privilege.accessor_id = ctx.user.id
179 & Privilege.accessor_type = "User"
180 & Privilege.permission = "role:admin"
181 & Privilege.object_type = "Site"
182 & Privilege.object_id = ctx.user.site.id) >
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400183"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700184 args = XOSProcessorArgs()
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400185 args.inputs = xproto
186 args.target = self.target
187
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800188 output = XOSProcessor.process(args)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400189
Zack Williams045b63d2019-01-22 16:30:57 -0700190 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400191
192 """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400193 def policy_output_enforcer(obj, ctx):
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400194 i2 = ctx.user.is_admin
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400195 i4 = (ctx.user.id == obj.id)
196 i5 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(permission='role:admin'), Q(object_type='Site'), Q(object_id=ctx.user.site.id))[0]
197 i3 = (i4 or i5)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400198 i1 = (i2 or i3)
199 return i1
200 """
201
202 # FIXME: Test this policy by executing it
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400203 self.assertTrue(policy_output_enforcer is not None)
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400204
Zack Williams045b63d2019-01-22 16:30:57 -0700205
206if __name__ == "__main__":
Sapan Bhatia3e3c1cd2017-07-15 01:35:44 -0400207 unittest.main()