diff --git a/setools/policyrep/rbacrule.py b/setools/policyrep/rbacrule.py index b0b1607..aa6a0d0 100644 --- a/setools/policyrep/rbacrule.py +++ b/setools/policyrep/rbacrule.py @@ -38,7 +38,7 @@ def validate_ruletype(types): """Validate RBAC rule types.""" for t in types: if t not in ["allow", "role_transition"]: - raise exception.InvalidTERuleType("{0} is not a valid RBAC rule type.".format(t)) + raise exception.InvalidRBACRuleType("{0} is not a valid RBAC rule type.".format(t)) class RoleAllow(rule.PolicyRule): diff --git a/tests/policyrep/__init__.py b/tests/policyrep/__init__.py index 53026f5..b8f98be 100644 --- a/tests/policyrep/__init__.py +++ b/tests/policyrep/__init__.py @@ -16,6 +16,7 @@ # along with SETools. If not, see . # from . import mls +from . import rbacrule from . import role from . import selinuxpolicy from . import terule diff --git a/tests/policyrep/rbacrule.py b/tests/policyrep/rbacrule.py new file mode 100644 index 0000000..255ee58 --- /dev/null +++ b/tests/policyrep/rbacrule.py @@ -0,0 +1,167 @@ +# Copyright 2015, Tresys Technology, LLC +# +# This file is part of SETools. +# +# SETools is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# SETools is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SETools. If not, see . +# +import unittest + +try: + from unittest.mock import Mock, patch +except ImportError: + from mock import Mock, patch + +from setools import SELinuxPolicy +from setools.policyrep.qpol import qpol_policy_t, qpol_role_allow_t, qpol_role_trans_t +from setools.policyrep.rbacrule import rbac_rule_factory, validate_ruletype, RoleAllow, \ + RoleTransition +from setools.policyrep.exception import InvalidRBACRuleType, RuleNotConditional, RuleUseError + + +@patch('setools.policyrep.role.role_factory', lambda x, y: y) +class RoleAllowTest(unittest.TestCase): + + def mock_avrule_factory(self, source, target): + mock_rule = Mock(qpol_role_allow_t) + mock_rule.rule_type.return_value = "allow" + mock_rule.source_role.return_value = source + mock_rule.target_role.return_value = target + + return rbac_rule_factory(self.p, mock_rule) + + def setUp(self): + self.p = Mock(qpol_policy_t) + + def test_000_factory(self): + """RoleAllow factory lookup.""" + with self.assertRaises(TypeError): + rbac_rule_factory(self.p, "INVALID") + + def test_001_validate_ruletype(self): + """RoleAllow valid rule types.""" + # no return value means a return of None + self.assertIsNone(validate_ruletype(["allow"])) + + def test_002_validate_ruletype_invalid(self): + """RoleAllow valid rule types.""" + with self.assertRaises(InvalidRBACRuleType): + self.assertTrue(validate_ruletype("range_transition")) + + def test_010_ruletype(self): + """RoleAllow rule type""" + rule = self.mock_avrule_factory("a", "b") + self.assertEqual("allow", rule.ruletype) + + def test_020_source_role(self): + """RoleAllow source role""" + rule = self.mock_avrule_factory("source20", "b") + self.assertEqual("source20", rule.source) + + def test_030_target_role(self): + """RoleAllow target role""" + rule = self.mock_avrule_factory("a", "target30") + self.assertEqual("target30", rule.target) + + def test_040_object_class(self): + """RoleAllow object class""" + rule = self.mock_avrule_factory("a", "b") + with self.assertRaises(RuleUseError): + rule.tclass + + def test_060_conditional(self): + """RoleAllow conditional expression""" + rule = self.mock_avrule_factory("a", "b") + with self.assertRaises(RuleNotConditional): + rule.conditional + + def test_070_default(self): + """RoleAllow default role""" + rule = self.mock_avrule_factory("a", "b") + with self.assertRaises(RuleUseError): + rule.default + + def test_100_statement_one_perm(self): + """RoleAllow statement.""" + rule = self.mock_avrule_factory("a", "b") + self.assertEqual("allow a b;", rule.statement()) + + +@patch('setools.policyrep.role.role_factory', lambda x, y: y) +@patch('setools.policyrep.typeattr.type_or_attr_factory', lambda x, y: y) +@patch('setools.policyrep.objclass.class_factory', lambda x, y: y) +class RoleTransitionTest(unittest.TestCase): + + def mock_roletrans_factory(self, source, target, tclass, default): + mock_rule = Mock(qpol_role_trans_t) + mock_rule.rule_type.return_value = "role_transition" + mock_rule.source_role.return_value = source + mock_rule.target_type.return_value = target + mock_rule.object_class.return_value = tclass + mock_rule.default_role.return_value = default + + return rbac_rule_factory(self.p, mock_rule) + + def setUp(self): + self.p = Mock(qpol_policy_t) + + def test_000_factory(self): + """RoleTransition factory lookup.""" + with self.assertRaises(TypeError): + rbac_rule_factory(self.p, "INVALID") + + def test_001_validate_ruletype(self): + """RoleTransition valid rule types.""" + # no return value means a return of None + self.assertIsNone(validate_ruletype(["role_transition"])) + + def test_002_validate_ruletype_invalid(self): + """RoleTransition valid rule types.""" + with self.assertRaises(InvalidRBACRuleType): + self.assertTrue(validate_ruletype("type_transition")) + + def test_010_ruletype(self): + """RoleTransition rule type""" + rule = self.mock_roletrans_factory("a", "b", "c", "d") + self.assertEqual("role_transition", rule.ruletype) + + def test_020_source_role(self): + """RoleTransition source role""" + rule = self.mock_roletrans_factory("source20", "b", "c", "d") + self.assertEqual("source20", rule.source) + + def test_030_target_type(self): + """RoleTransition target type""" + rule = self.mock_roletrans_factory("a", "target30", "c", "d") + self.assertEqual("target30", rule.target) + + def test_040_object_class(self): + """RoleTransition object class""" + rule = self.mock_roletrans_factory("a", "b", "class40", "d") + self.assertEqual("class40", rule.tclass) + + def test_050_default(self): + """RoleTransition default role""" + rule = self.mock_roletrans_factory("a", "b", "c", "default50") + self.assertEqual("default50", rule.default) + + def test_060_conditional(self): + """RoleTransition conditional expression""" + rule = self.mock_roletrans_factory("a", "b", "c", "d") + with self.assertRaises(RuleNotConditional): + rule.conditional + + def test_100_statement(self): + """RoleTransition statement.""" + rule = self.mock_roletrans_factory("a", "b", "c", "d") + self.assertEqual("role_transition a b:c d;", rule.statement())