mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
checker: Implement RBAC rule assertion check.
Signed-off-by: Chris PeBenito <pebenito@ieee.org>
This commit is contained in:
parent
56b2fd1f47
commit
83f91adb2c
@ -108,6 +108,42 @@ in the expect_source list or exempt_source list to pass. Similarly, if a rule h
|
||||
an attribute target, all of the member types must be in the expect_target list or
|
||||
exempt_target list to pass.
|
||||
|
||||
.SH "ROLE BASED ACCESS CONTROL ALLOW RULE ASSERTION"
|
||||
This checks for the nonexistence of role based access control (RBAC) allow rules. The
|
||||
check_type is \fBassert_rbac\fR. It will run the query and any unexpected results
|
||||
from the query, removing any exempted sources or targets, will be listed as failures.
|
||||
Any expected results that are not seen will also be listed as failures.
|
||||
|
||||
.PP
|
||||
Criteria options:
|
||||
.IP "source = <role"
|
||||
The source role criteria for the query.
|
||||
.IP "target = <role>"
|
||||
The target role criteria for the query.
|
||||
|
||||
.PP
|
||||
\fBA least one of the above options must be set in this check.\fR
|
||||
|
||||
.PP
|
||||
Additional Options:
|
||||
|
||||
.IP "expect_source = <role>[ ....]"
|
||||
A space-separated list of roles. Each of these
|
||||
roles must be seen as the source of a rule that matches the criteria.
|
||||
At the end of the query, each unseen role in this list will be reported
|
||||
as a failure. This is optional.
|
||||
.IP "expect_target = <role>[ ....]"
|
||||
A space-separated list of roles. Each of these
|
||||
roles must be seen as the target of a rule that matches the criteria.
|
||||
At the end of the query, each unseen role in this list will be reported
|
||||
as a failure. This is optional.
|
||||
.IP "exempt_source = <role>[ ....]"
|
||||
A space-separated list of roles. Rules with these
|
||||
as the source will be ignored. This is optional.
|
||||
.IP "exempt_target = <role>[ ....]"
|
||||
A space-separated list of roles. Rules with these
|
||||
as the target will be ignored. This is optional.
|
||||
|
||||
.SH "EMPTY TYPE ATTRIBUTE ASSERTION"
|
||||
This checks that the specified attribute is empty. This can optionally
|
||||
be set to also pass if the attribute does not exist.
|
||||
|
116
setools/checker/assertrbac.py
Normal file
116
setools/checker/assertrbac.py
Normal file
@ -0,0 +1,116 @@
|
||||
# Copyright 2020, Microsoft Corporation
|
||||
# Copyright 2020, Chris PeBenito <pebenito@ieee.org>
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
from ..exception import InvalidCheckValue, InvalidClass
|
||||
from ..rbacrulequery import RBACRuleQuery
|
||||
from .checkermodule import CheckerModule
|
||||
from .descriptors import ConfigDescriptor, ConfigSetDescriptor
|
||||
|
||||
SOURCE_OPT = "source"
|
||||
TARGET_OPT = "target"
|
||||
EXEMPT_SRC_OPT = "exempt_source"
|
||||
EXEMPT_TGT_OPT = "exempt_target"
|
||||
EXPECT_SRC_OPT = "expect_source"
|
||||
EXPECT_TGT_OPT = "expect_target"
|
||||
|
||||
|
||||
class AssertRBAC(CheckerModule):
|
||||
|
||||
"""Checker module for asserting a RBAC allow rule exists (or not)."""
|
||||
|
||||
check_type = "assert_rbac"
|
||||
check_config = frozenset((SOURCE_OPT, TARGET_OPT, EXEMPT_SRC_OPT, EXEMPT_TGT_OPT,
|
||||
EXPECT_SRC_OPT, EXPECT_TGT_OPT))
|
||||
|
||||
source = ConfigDescriptor("lookup_role")
|
||||
target = ConfigDescriptor("lookup_role")
|
||||
|
||||
exempt_source = ConfigSetDescriptor("lookup_role", strict=False, expand=True)
|
||||
exempt_target = ConfigSetDescriptor("lookup_role", strict=False, expand=True)
|
||||
expect_source = ConfigSetDescriptor("lookup_role", strict=True, expand=True)
|
||||
expect_target = ConfigSetDescriptor("lookup_role", strict=True, expand=True)
|
||||
|
||||
def __init__(self, policy, checkname, config):
|
||||
super().__init__(policy, checkname, config)
|
||||
self.log = logging.getLogger(__name__)
|
||||
|
||||
self.source = config.get(SOURCE_OPT)
|
||||
self.target = config.get(TARGET_OPT)
|
||||
|
||||
self.exempt_source = config.get(EXEMPT_SRC_OPT)
|
||||
self.exempt_target = config.get(EXEMPT_TGT_OPT)
|
||||
self.expect_source = config.get(EXPECT_SRC_OPT)
|
||||
self.expect_target = config.get(EXPECT_TGT_OPT)
|
||||
|
||||
if not any((self.source, self.target)):
|
||||
raise InvalidCheckValue(
|
||||
"At least one of source or target options must be set.")
|
||||
|
||||
source_exempt_expect_overlap = self.exempt_source & self.expect_source
|
||||
if source_exempt_expect_overlap:
|
||||
self.log.info("Overlap in expect_source and exempt_source: {}".
|
||||
format(", ".join(i.name for i in source_exempt_expect_overlap)))
|
||||
|
||||
target_exempt_expect_overlap = self.exempt_target & self.expect_target
|
||||
if target_exempt_expect_overlap:
|
||||
self.log.info("Overlap in expect_target and exempt_target: {}".
|
||||
format(", ".join(i.name for i in target_exempt_expect_overlap)))
|
||||
|
||||
def run(self):
|
||||
assert any((self.source, self.target)), "AssertRBAC no options set, this is a bug."
|
||||
|
||||
self.log.info("Checking RBAC allow rule assertion.")
|
||||
|
||||
query = RBACRuleQuery(self.policy,
|
||||
source=self.source,
|
||||
target=self.target,
|
||||
ruletype=("allow",))
|
||||
|
||||
unseen_sources = set(self.expect_source)
|
||||
unseen_targets = set(self.expect_target)
|
||||
failures = []
|
||||
for rule in sorted(query.results()):
|
||||
srcs = set(rule.source.expand())
|
||||
tgts = set(rule.target.expand())
|
||||
|
||||
unseen_sources -= srcs
|
||||
unseen_targets -= tgts
|
||||
if (srcs - self.expect_source - self.exempt_source) and \
|
||||
(tgts - self.expect_target - self.exempt_target):
|
||||
|
||||
self.log_fail(str(rule))
|
||||
failures.append(rule)
|
||||
else:
|
||||
self.log_ok(str(rule))
|
||||
|
||||
for item in unseen_sources:
|
||||
failure = "Expected rule with source \"{}\" not found.".format(item)
|
||||
self.log_fail(failure)
|
||||
failures.append(failure)
|
||||
|
||||
for item in unseen_targets:
|
||||
failure = "Expected rule with target \"{}\" not found.".format(item)
|
||||
self.log_fail(failure)
|
||||
failures.append(failure)
|
||||
|
||||
self.log.debug("{} failure(s)".format(failures))
|
||||
return failures
|
@ -17,6 +17,7 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from . import assertrbac
|
||||
from . import assertte
|
||||
from . import checker
|
||||
from . import emptyattr
|
||||
|
181
tests/checker/assertrbac.conf
Normal file
181
tests/checker/assertrbac.conf
Normal file
@ -0,0 +1,181 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity low_s;
|
||||
sensitivity medium_s alias med;
|
||||
sensitivity high_s;
|
||||
|
||||
dominance { low_s med high_s }
|
||||
|
||||
category here;
|
||||
category there;
|
||||
category elsewhere alias lost;
|
||||
|
||||
#level decl
|
||||
level low_s:here.there;
|
||||
level med:here, elsewhere;
|
||||
level high_s:here.lost;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
################################################################################
|
||||
# Type enforcement declarations and rules
|
||||
|
||||
type test1a;
|
||||
type test1b;
|
||||
allow test1a test1b:infoflow hi_w;
|
||||
|
||||
################################################################################
|
||||
|
||||
# Roles for config tests:
|
||||
role src;
|
||||
role tgt;
|
||||
role exempt_src1;
|
||||
role exempt_tgt1;
|
||||
role exempt_src2;
|
||||
role exempt_tgt2;
|
||||
|
||||
role exempt_source_role;
|
||||
role exempt_target_role;
|
||||
|
||||
# pass, exempt source
|
||||
role source1;
|
||||
role target1;
|
||||
allow source1 target1;
|
||||
|
||||
# pass, exempt target
|
||||
role source2;
|
||||
role target2;
|
||||
allow source2 target2;
|
||||
|
||||
# pass, expect source
|
||||
role source3a;
|
||||
role source3b;
|
||||
role target3;
|
||||
allow source3a target3;
|
||||
allow source3b target3;
|
||||
|
||||
# pass, expect target
|
||||
role source4;
|
||||
role target4a;
|
||||
role target4b;
|
||||
allow source4 target4a;
|
||||
allow source4 target4b;
|
||||
|
||||
# pass, expected and exempt sources
|
||||
role source5a;
|
||||
role source5b;
|
||||
role target5;
|
||||
allow source5a target5;
|
||||
allow source5b target5;
|
||||
|
||||
# pass, expected and exempt targets
|
||||
role source6;
|
||||
role target6a;
|
||||
role target6b;
|
||||
allow source6 target6a;
|
||||
allow source6 target6b;
|
||||
|
||||
# fail
|
||||
role source7;
|
||||
role target7a;
|
||||
role target7b;
|
||||
role target7c;
|
||||
allow source7 target7a;
|
||||
allow source7 target7b;
|
||||
allow source7 target7c;
|
||||
|
||||
# fail, expect source
|
||||
role source8;
|
||||
role target8;
|
||||
|
||||
# fail, expect target
|
||||
role source9;
|
||||
role target9;
|
||||
|
||||
#users
|
||||
user system roles system level med range low_s - high_s:here.lost;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:medium_s:here
|
||||
sid security system:system:system:high_s:lost
|
||||
|
||||
#fs_use
|
||||
fs_use_trans devpts system:object_r:system:low_s;
|
||||
fs_use_xattr ext3 system:object_r:system:low_s;
|
||||
fs_use_task pipefs system:object_r:system:low_s;
|
||||
|
||||
#genfscon
|
||||
genfscon proc / system:object_r:system:med
|
||||
genfscon proc /sys system:object_r:system:low_s
|
||||
genfscon selinuxfs / system:object_r:system:high_s:here.there
|
||||
|
||||
portcon tcp 80 system:object_r:system:low_s
|
||||
|
||||
netifcon eth0 system:object_r:system:low_s system:object_r:system:low_s
|
||||
|
||||
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:low_s:here
|
||||
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:low_s:here
|
||||
|
250
tests/checker/assertrbac.py
Normal file
250
tests/checker/assertrbac.py
Normal file
@ -0,0 +1,250 @@
|
||||
# Copyright 2020, Microsoft Corporation
|
||||
# Copyright 2020, Chris PeBenito <pebenito@ieee.org>
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from ..policyrep.util import compile_policy
|
||||
|
||||
from setools import RBACRuletype
|
||||
from setools.checker.assertrbac import AssertRBAC
|
||||
from setools.exception import InvalidCheckValue, InvalidCheckOption
|
||||
|
||||
|
||||
class AssertRBACTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = compile_policy("tests/checker/assertrbac.conf")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.unlink(cls.p.path)
|
||||
|
||||
def test_unconfigured(self):
|
||||
"""Test unconfigured."""
|
||||
with self.assertRaises(InvalidCheckValue):
|
||||
config = {}
|
||||
check = AssertRBAC(self.p, "test_unconfigured", config)
|
||||
|
||||
def test_invalid_option(self):
|
||||
"""Test invalid option"""
|
||||
with self.assertRaises(InvalidCheckOption):
|
||||
config = {"INVALID": "option"}
|
||||
check = AssertRBAC(self.p, "test_invalid_option", config)
|
||||
|
||||
def test_source(self):
|
||||
"""Test source setting."""
|
||||
|
||||
with self.subTest("Success"):
|
||||
config = {"source": "src"}
|
||||
check = AssertRBAC(self.p, "test_source", config)
|
||||
|
||||
expected = self.p.lookup_role("src")
|
||||
self.assertEqual(expected, check.source)
|
||||
|
||||
with self.subTest("Failure"):
|
||||
with self.assertRaises(InvalidCheckValue):
|
||||
config = {"source": "FAIL"}
|
||||
check = AssertRBAC(self.p, "test_source_fail", config)
|
||||
|
||||
def test_target(self):
|
||||
"""Test target setting."""
|
||||
|
||||
with self.subTest("Success"):
|
||||
config = {"target": "tgt"}
|
||||
check = AssertRBAC(self.p, "test_target", config)
|
||||
|
||||
expected = self.p.lookup_role("tgt")
|
||||
self.assertEqual(expected, check.target)
|
||||
|
||||
with self.subTest("Failure"):
|
||||
with self.assertRaises(InvalidCheckValue):
|
||||
config = {"target": "FAIL2"}
|
||||
check = AssertRBAC(self.p, "test_target_fail", config)
|
||||
|
||||
def test_exempt_source(self):
|
||||
"""Test exempt_source setting."""
|
||||
with self.subTest("Success"):
|
||||
config = {"source": "system",
|
||||
"exempt_source": " exempt_src1 exempt_src2 "}
|
||||
check = AssertRBAC(self.p, "test_exempt_source", config)
|
||||
|
||||
# exempt_src2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_src1"),
|
||||
self.p.lookup_role("exempt_src2")))
|
||||
self.assertIsInstance(check.exempt_source, frozenset)
|
||||
self.assertSetEqual(expected, check.exempt_source)
|
||||
|
||||
with self.subTest("Success, missing role ignored"):
|
||||
"""Test exempt_source missing role is ignroed."""
|
||||
config = {"source": "system",
|
||||
"exempt_source": "FAIL exempt_src2"}
|
||||
check = AssertRBAC(self.p, "test_source_missing_ignored", config)
|
||||
|
||||
# exempt_src2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_src2"),))
|
||||
self.assertIsInstance(check.exempt_source, frozenset)
|
||||
self.assertSetEqual(expected, check.exempt_source)
|
||||
|
||||
def test_exempt_target(self):
|
||||
"""Test exempt_target setting."""
|
||||
with self.subTest("Success"):
|
||||
config = {"target": "system",
|
||||
"exempt_target": " exempt_tgt1 exempt_tgt2 "}
|
||||
check = AssertRBAC(self.p, "test_exempt_target", config)
|
||||
|
||||
# exempt_tgt2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_tgt1"),
|
||||
self.p.lookup_role("exempt_tgt2")))
|
||||
self.assertIsInstance(check.exempt_target, frozenset)
|
||||
self.assertSetEqual(expected, check.exempt_target)
|
||||
|
||||
with self.subTest("Success, missing role ignored"):
|
||||
config = {"target": "system",
|
||||
"exempt_target": "FAIL exempt_tgt2"}
|
||||
check = AssertRBAC(self.p, "test_target_missing_ignored", config)
|
||||
|
||||
# exempt_tgt2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_tgt2"),))
|
||||
self.assertIsInstance(check.exempt_target, frozenset)
|
||||
self.assertSetEqual(expected, check.exempt_target)
|
||||
|
||||
def test_expect_source(self):
|
||||
"""Test expect_source setting."""
|
||||
with self.subTest("Success"):
|
||||
config = {"target": "tgt",
|
||||
"expect_source": " exempt_src1 exempt_src2 "}
|
||||
check = AssertRBAC(self.p, "test_expect_source", config)
|
||||
|
||||
# exempt_src2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_src1"),
|
||||
self.p.lookup_role("exempt_src2")))
|
||||
self.assertIsInstance(check.expect_source, frozenset)
|
||||
self.assertSetEqual(expected, check.expect_source)
|
||||
|
||||
with self.subTest("Failure"):
|
||||
with self.assertRaises(InvalidCheckValue):
|
||||
config = {"target": "tgt",
|
||||
"expect_source": " source1 INVALID "}
|
||||
check = AssertRBAC(self.p, "test_expect_source_fail", config)
|
||||
|
||||
def test_expect_target(self):
|
||||
"""Test expect_target setting."""
|
||||
with self.subTest("Success"):
|
||||
config = {"source": "src",
|
||||
"expect_target": " exempt_tgt1 exempt_tgt2 "}
|
||||
check = AssertRBAC(self.p, "test_expect_target", config)
|
||||
|
||||
# exempt_tgt2 is an attr
|
||||
expected = set((self.p.lookup_role("exempt_tgt1"),
|
||||
self.p.lookup_role("exempt_tgt2")))
|
||||
self.assertIsInstance(check.expect_target, frozenset)
|
||||
self.assertSetEqual(expected, check.expect_target)
|
||||
|
||||
with self.subTest("Failure"):
|
||||
with self.assertRaises(InvalidCheckValue):
|
||||
config = {"source": "src",
|
||||
"expect_target": " target1 INVALID "}
|
||||
check = AssertRBAC(self.p, "test_expect_target_fail", config)
|
||||
|
||||
def test_check_passes(self):
|
||||
"""Test the check passes, no matches"""
|
||||
config = {"source": "src",
|
||||
"target": "tgt"}
|
||||
check = AssertRBAC(self.p, "test_check_passes", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_exempt_source_role(self):
|
||||
"""Test the check passes, exempt_source_role"""
|
||||
config = {"target": "target1",
|
||||
"exempt_source": "source1"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_exempt_source_role", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_exempt_target_role(self):
|
||||
"""Test the check passes, exempt_target_role"""
|
||||
config = {"target": "target2",
|
||||
"exempt_source": "source2"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_exempt_target_role", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_expect_source(self):
|
||||
"""Test the check passes, expect_source"""
|
||||
config = {"target": "target3",
|
||||
"expect_source": "source3a source3b"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_expect_source", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_expect_target(self):
|
||||
"""Test the check passes, expect_target"""
|
||||
config = {"source": "source4",
|
||||
"expect_target": "target4a target4b"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_expect_target", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_expect_exempt_source(self):
|
||||
""""Test the check passes with both expected and exempted sources."""
|
||||
config = {"target": "target5",
|
||||
"expect_source": "source5a",
|
||||
"exempt_source": "source5b"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_expect_exempt_source", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_passes_expect_exempt_target(self):
|
||||
""""Test the check passes with both expected and exempted targets."""
|
||||
config = {"source": "source6",
|
||||
"expect_target": "target6a",
|
||||
"exempt_target": "target6b"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_expect_exempt_target", config)
|
||||
self.assertFalse(check.run())
|
||||
|
||||
def test_check_fails(self):
|
||||
"""Test the check fails"""
|
||||
with open("/dev/null", "w") as fd:
|
||||
config = {"source": "source7",
|
||||
"expect_target": "target7a",
|
||||
"exempt_target": "target7b"}
|
||||
check = AssertRBAC(self.p, "test_check_passes_exempt_target_attr", config)
|
||||
check.output = fd
|
||||
result = check.run()
|
||||
self.assertEqual(1, len(result), msg=result)
|
||||
rule = result[0]
|
||||
self.assertEqual(RBACRuletype.allow, rule.ruletype)
|
||||
self.assertEqual("source7", rule.source)
|
||||
self.assertEqual("target7c", rule.target)
|
||||
|
||||
def test_check_fails_expect_source(self):
|
||||
"""Test the check fails, expect_source"""
|
||||
config = {"target": "target8",
|
||||
"expect_source": "source8"}
|
||||
check = AssertRBAC(self.p, "test_check_fails_expect_source", config)
|
||||
result = check.run()
|
||||
self.assertEqual(1, len(result), msg=result)
|
||||
self.assertIn("source8", result[0])
|
||||
|
||||
def test_check_fails_expect_target(self):
|
||||
"""Test the check fails, expect_target"""
|
||||
config = {"source": "source9",
|
||||
"expect_target": "target9"}
|
||||
check = AssertRBAC(self.p, "test_check_fails_expect_target", config)
|
||||
result = check.run()
|
||||
self.assertEqual(1, len(result), msg=result)
|
||||
self.assertIn("target9", result[0])
|
Loading…
Reference in New Issue
Block a user