mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 05:47:59 +00:00
Add IncludeRule and IncludeRuleset including tests
These classes are meant to handle 'include' and 'include if exists' rules. Due to restrictions in re_match_include_parse(), some cases in is_covered_localvars() and is_equal_localvars() can't be reached in the unittests. Also, IncludeRule isn't used in aa-logprof (yet?), which means logprof_header_localvars() result format isn't decided yet, and therefore not tested. This means test coverage for the new classes isn't 100% this time ;-)
This commit is contained in:
parent
6b9b928f9d
commit
4df5ac780d
130
utils/apparmor/rule/include.py
Normal file
130
utils/apparmor/rule/include.py
Normal file
@ -0,0 +1,130 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2020 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.regex import RE_INCLUDE, re_match_include_parse
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_comment
|
||||
|
||||
# setup module translations
|
||||
from apparmor.translations import init_translation
|
||||
_ = init_translation()
|
||||
|
||||
|
||||
class IncludeRule(BaseRule):
|
||||
'''Class to handle and store a single include rule'''
|
||||
|
||||
rule_name = 'include'
|
||||
|
||||
def __init__(self, path, ifexists, ismagic, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
|
||||
super(IncludeRule, self).__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
|
||||
# include doesn't support audit or deny
|
||||
if audit:
|
||||
raise AppArmorBug('Attempt to initialize IncludeRule with audit flag')
|
||||
if deny:
|
||||
raise AppArmorBug('Attempt to initialize IncludeRule with deny flag')
|
||||
|
||||
if type(ifexists) is not bool:
|
||||
raise AppArmorBug('Passed unknown type for ifexists to IncludeRule: %s' % ifexists)
|
||||
if type(ismagic) is not bool:
|
||||
raise AppArmorBug('Passed unknown type for ismagic to IncludeRule: %s' % ismagic)
|
||||
if not type_is_str(path):
|
||||
raise AppArmorBug('Passed unknown type for path to IncludeRule: %s' % path)
|
||||
if not path:
|
||||
raise AppArmorBug('Passed empty path to IncludeRule: %s' % path)
|
||||
|
||||
self.path = path
|
||||
self.ifexists = ifexists
|
||||
self.ismagic = ismagic
|
||||
|
||||
@classmethod
|
||||
def _match(cls, raw_rule):
|
||||
return RE_INCLUDE.search(raw_rule)
|
||||
|
||||
@classmethod
|
||||
def _parse(cls, raw_rule):
|
||||
'''parse raw_rule and return IncludeRule'''
|
||||
|
||||
matches = cls._match(raw_rule)
|
||||
if not matches:
|
||||
raise AppArmorException(_("Invalid include rule '%s'") % raw_rule)
|
||||
|
||||
comment = parse_comment(matches)
|
||||
|
||||
# TODO: move re_match_include_parse() from regex.py to this class after converting all code to use IncludeRule
|
||||
path, ifexists, ismagic = re_match_include_parse(raw_rule)
|
||||
|
||||
return IncludeRule(path, ifexists, ismagic,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
'''return rule (in clean/default formatting)'''
|
||||
|
||||
space = ' ' * depth
|
||||
|
||||
ifexists_txt = ''
|
||||
if self.ifexists:
|
||||
ifexists_txt = ' if exists'
|
||||
|
||||
if self.ismagic:
|
||||
return('%sinclude%s <%s>%s' % (space, ifexists_txt, self.path, self.comment))
|
||||
else:
|
||||
return('%sinclude%s "%s"%s' % (space, ifexists_txt, self.path, self.comment))
|
||||
|
||||
def is_covered_localvars(self, other_rule):
|
||||
'''check if other_rule is covered by this rule object'''
|
||||
|
||||
if (self.path != other_rule.path):
|
||||
return False
|
||||
|
||||
if (self.ifexists != other_rule.ifexists) and (self.ifexists == True): # "if exists" is allowed to differ
|
||||
return False
|
||||
|
||||
if (self.ismagic != other_rule.ismagic):
|
||||
return False
|
||||
|
||||
# still here? -> then it is covered
|
||||
return True
|
||||
|
||||
def is_equal_localvars(self, rule_obj, strict):
|
||||
'''compare if rule-specific variables are equal'''
|
||||
|
||||
if not type(rule_obj) == IncludeRule:
|
||||
raise AppArmorBug('Passed non-include rule: %s' % str(rule_obj))
|
||||
|
||||
if (self.path != rule_obj.path):
|
||||
return False
|
||||
|
||||
if (self.ifexists != rule_obj.ifexists):
|
||||
return False
|
||||
|
||||
if (self.ismagic != rule_obj.ismagic):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def logprof_header_localvars(self):
|
||||
return [
|
||||
_('Include'), self.get_clean(),
|
||||
]
|
||||
|
||||
|
||||
class IncludeRuleset(BaseRuleset):
|
||||
'''Class to handle and store a collection of include rules'''
|
||||
pass
|
426
utils/test/test-include.py
Normal file
426
utils/test/test-include.py
Normal file
@ -0,0 +1,426 @@
|
||||
#!/usr/bin/python3
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2020 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
from collections import namedtuple
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
from apparmor.rule.include import IncludeRule, IncludeRuleset
|
||||
#from apparmor.rule import BaseRule
|
||||
from apparmor.common import AppArmorException, AppArmorBug
|
||||
#from apparmor.logparser import ReadLog
|
||||
from apparmor.translations import init_translation
|
||||
_ = init_translation()
|
||||
|
||||
exp = namedtuple('exp', [ # 'audit', 'allow_keyword', 'deny',
|
||||
'comment',
|
||||
'path', 'ifexists', 'ismagic'])
|
||||
|
||||
# --- tests for single IncludeRule --- #
|
||||
|
||||
class IncludeTest(AATest):
|
||||
def _compare_obj(self, obj, expected):
|
||||
self.assertEqual(False, obj.allow_keyword) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(False, obj.audit) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(False, obj.deny) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(expected.comment, obj.comment)
|
||||
|
||||
self.assertEqual(expected.path, obj.path)
|
||||
self.assertEqual(expected.ifexists, obj.ifexists)
|
||||
self.assertEqual(expected.ismagic, obj.ismagic)
|
||||
|
||||
class IncludeTestParse(IncludeTest):
|
||||
tests = [
|
||||
# IncludeRule object comment path if exists ismagic
|
||||
# #include
|
||||
('#include <abstractions/base>', exp('', 'abstractions/base', False, True )), # magic path
|
||||
('#include <abstractions/base> # comment', exp(' # comment', 'abstractions/base', False, True )),
|
||||
('#include<abstractions/base>#comment', exp(' #comment', 'abstractions/base', False, True )),
|
||||
(' #include <abstractions/base> ', exp('', 'abstractions/base', False, True )),
|
||||
('#include "/foo/bar"', exp('', '/foo/bar', False, False)), # absolute path
|
||||
('#include "/foo/bar" # comment', exp(' # comment', '/foo/bar', False, False)),
|
||||
('#include "/foo/bar"#comment', exp(' #comment', '/foo/bar', False, False)),
|
||||
(' #include "/foo/bar" ', exp('', '/foo/bar', False, False)),
|
||||
# include (without #)
|
||||
('include <abstractions/base>', exp('', 'abstractions/base', False, True )), # magic path
|
||||
('include <abstractions/base> # comment', exp(' # comment', 'abstractions/base', False, True )),
|
||||
('include<abstractions/base>#comment', exp(' #comment', 'abstractions/base', False, True )),
|
||||
(' include <abstractions/base> ', exp('', 'abstractions/base', False, True )),
|
||||
('include "/foo/bar"', exp('', '/foo/bar', False, False)), # absolute path
|
||||
('include "/foo/bar" # comment', exp(' # comment', '/foo/bar', False, False)),
|
||||
('include "/foo/bar"#comment', exp(' #comment', '/foo/bar', False, False)),
|
||||
(' include "/foo/bar" ', exp('', '/foo/bar', False, False)),
|
||||
# #include if exists
|
||||
('#include if exists <abstractions/base>', exp('', 'abstractions/base', True, True )), # magic path
|
||||
('#include if exists <abstractions/base> # comment', exp(' # comment', 'abstractions/base', True, True )),
|
||||
('#include if exists<abstractions/base>#comment', exp(' #comment', 'abstractions/base', True, True )),
|
||||
(' #include if exists<abstractions/base> ', exp('', 'abstractions/base', True, True )),
|
||||
('#include if exists "/foo/bar"', exp('', '/foo/bar', True, False)), # absolute path
|
||||
('#include if exists "/foo/bar" # comment', exp(' # comment', '/foo/bar', True, False)),
|
||||
('#include if exists "/foo/bar"#comment', exp(' #comment', '/foo/bar', True, False)),
|
||||
(' #include if exists "/foo/bar" ', exp('', '/foo/bar', True, False)),
|
||||
# include if exists (without #)
|
||||
('include if exists <abstractions/base>', exp('', 'abstractions/base', True, True )), # magic path
|
||||
('include if exists <abstractions/base> # comment', exp(' # comment', 'abstractions/base', True, True )),
|
||||
('include if exists<abstractions/base>#comment', exp(' #comment', 'abstractions/base', True, True )),
|
||||
(' include if exists<abstractions/base> ', exp('', 'abstractions/base', True, True )),
|
||||
('include if exists "/foo/bar"', exp('', '/foo/bar', True, False)), # absolute path
|
||||
('include if exists "/foo/bar" # comment', exp(' # comment', '/foo/bar', True, False)),
|
||||
('include if exists "/foo/bar"#comment', exp(' #comment', '/foo/bar', True, False)),
|
||||
(' include if exists "/foo/bar" ', exp('', '/foo/bar', True, False)),
|
||||
]
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
self.assertTrue(IncludeRule.match(rawrule))
|
||||
obj = IncludeRule.parse(rawrule)
|
||||
self.assertEqual(rawrule.strip(), obj.raw_rule)
|
||||
self._compare_obj(obj, expected)
|
||||
|
||||
class IncludeTestParseInvalid(IncludeTest):
|
||||
tests = [
|
||||
# (' some #include if exists <abstractions/base>', AppArmorException),
|
||||
# (' /etc/fstab r,', AppArmorException),
|
||||
# ('/usr/include r,', AppArmorException),
|
||||
# ('/include r,', AppArmorException),
|
||||
]
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
self.assertTrue(IncludeRule.match(rawrule)) # the above invalid rules still match the main regex!
|
||||
with self.assertRaises(expected):
|
||||
IncludeRule.parse(rawrule)
|
||||
|
||||
# class IncludeTestParseFromLog(IncludeTest): # we'll never have log events for includes
|
||||
|
||||
class IncludeFromInit(IncludeTest):
|
||||
tests = [
|
||||
# IncludeRule object ifexists ismagic comment path ifexists ismagic
|
||||
(IncludeRule('abstractions/base', False, False) , exp('', 'abstractions/base', False, False )),
|
||||
(IncludeRule('foo', True, False) , exp('', 'foo', True, False )),
|
||||
(IncludeRule('bar', False, True) , exp('', 'bar', False, True )),
|
||||
(IncludeRule('baz', True, True) , exp('', 'baz', True, True )),
|
||||
(IncludeRule('comment', False, False, comment='# cmt') , exp('# cmt', 'comment', False, False )),
|
||||
]
|
||||
|
||||
def _run_test(self, obj, expected):
|
||||
self._compare_obj(obj, expected)
|
||||
|
||||
class InvalidIncludeInit(AATest):
|
||||
tests = [
|
||||
# init params expected exception
|
||||
([False, False, False ] , AppArmorBug), # wrong type for path
|
||||
(['', False, False ] , AppArmorBug), # empty path
|
||||
([None, False, False ] , AppArmorBug), # wrong type for path
|
||||
# ([' ', False, False ] , AppArmorBug), # whitespace-only path
|
||||
(['foo', None, False ] , AppArmorBug), # wrong type for ifexists
|
||||
(['foo', '', False ] , AppArmorBug), # wrong type for ifexists
|
||||
(['foo', False, None ] , AppArmorBug), # wrong type for ismagic
|
||||
(['foo', False, '' ] , AppArmorBug), # wrong type for ismagic
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
with self.assertRaises(expected):
|
||||
IncludeRule(params[0], params[1], params[2])
|
||||
|
||||
def test_missing_params_1(self):
|
||||
with self.assertRaises(TypeError):
|
||||
IncludeRule()
|
||||
|
||||
def test_missing_params_2(self):
|
||||
with self.assertRaises(TypeError):
|
||||
IncludeRule('foo')
|
||||
|
||||
def test_missing_params_3(self):
|
||||
with self.assertRaises(TypeError):
|
||||
IncludeRule('foo', False)
|
||||
|
||||
def test_audit_true(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
IncludeRule('foo', False, False, audit=True)
|
||||
|
||||
def test_deny_true(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
IncludeRule('foo', False, False, deny=True)
|
||||
|
||||
class InvalidIncludeTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule, matches_regex = False):
|
||||
obj = None
|
||||
self.assertEqual(IncludeRule.match(rawrule), matches_regex)
|
||||
with self.assertRaises(AppArmorException):
|
||||
obj = IncludeRule.parse(rawrule)
|
||||
|
||||
self.assertIsNone(obj, 'IncludeRule handed back an object unexpectedly')
|
||||
|
||||
def test_invalid_include_missing_path(self):
|
||||
self._check_invalid_rawrule('include', matches_regex=True) # missing path
|
||||
|
||||
def test_invalid_non_IncludeRule(self):
|
||||
self._check_invalid_rawrule('dbus,') # not a include rule
|
||||
|
||||
# def test_empty_data_1(self):
|
||||
# obj = IncludeRule('foo', False, False)
|
||||
# obj.path = ''
|
||||
# # no path set
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.get_clean(1)
|
||||
|
||||
class WriteIncludeTestAATest(AATest):
|
||||
def _run_test(self, rawrule, expected):
|
||||
self.assertTrue(IncludeRule.match(rawrule))
|
||||
obj = IncludeRule.parse(rawrule)
|
||||
clean = obj.get_clean()
|
||||
raw = obj.get_raw()
|
||||
|
||||
self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
|
||||
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
|
||||
|
||||
tests = [
|
||||
# raw rule clean rule
|
||||
(' include <foo> ', 'include <foo>' ),
|
||||
# (' include foo ', 'include "foo"' ), # several test cases disabled due to implementation restrictions, see re_match_include_parse()
|
||||
# (' include "foo" ', 'include "foo"' ),
|
||||
# (' include /foo ', 'include "/foo"' ),
|
||||
(' include "/foo" ', 'include "/foo"' ),
|
||||
|
||||
(' include <foo> # bar ', 'include <foo> # bar' ),
|
||||
# (' include foo # bar ', 'include "foo" # bar' ),
|
||||
# (' include "foo" # bar ', 'include "foo" # bar' ),
|
||||
# (' include /foo # bar ', 'include "/foo" # bar' ),
|
||||
(' include "/foo" # bar ', 'include "/foo" # bar' ),
|
||||
|
||||
(' include if exists <foo> ', 'include if exists <foo>' ),
|
||||
# (' include if exists foo ', 'include if exists "foo"' ),
|
||||
# (' include if exists "foo" ', 'include if exists "foo"' ),
|
||||
# (' include if exists /foo ', 'include if exists "/foo"' ),
|
||||
(' include if exists "/foo" ', 'include if exists "/foo"' ),
|
||||
|
||||
# and the same again with #include...
|
||||
(' #include <foo> ', 'include <foo>' ),
|
||||
# (' #include foo ', 'include "foo"' ),
|
||||
# (' #include "foo" ', 'include "foo"' ),
|
||||
# (' #include /foo ', 'include "/foo"' ),
|
||||
(' #include "/foo" ', 'include "/foo"' ),
|
||||
|
||||
(' #include <foo> # bar ', 'include <foo> # bar' ),
|
||||
# (' #include foo # bar ', 'include "foo" # bar' ),
|
||||
# (' #include "foo" # bar ', 'include "foo" # bar' ),
|
||||
# (' #include /foo # bar ', 'include "/foo" # bar' ),
|
||||
(' #include "/foo" # bar ', 'include "/foo" # bar' ),
|
||||
|
||||
(' #include if exists <foo> ', 'include if exists <foo>' ),
|
||||
# (' #include if exists foo ', 'include if exists "foo"' ),
|
||||
# (' #include if exists "foo" ', 'include if exists "foo"' ),
|
||||
# (' #include if exists /foo ', 'include if exists "/foo"' ),
|
||||
(' #include if exists "/foo" ', 'include if exists "/foo"' ),
|
||||
]
|
||||
|
||||
def test_write_manually(self):
|
||||
obj = IncludeRule('abs/foo', False, True, comment=' # cmt')
|
||||
|
||||
expected = ' include <abs/foo> # cmt'
|
||||
|
||||
self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule')
|
||||
self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule')
|
||||
|
||||
|
||||
class IncludeCoveredTest(AATest):
|
||||
def _run_test(self, param, expected):
|
||||
obj = IncludeRule.parse(self.rule)
|
||||
check_obj = IncludeRule.parse(param)
|
||||
|
||||
self.assertTrue(IncludeRule.match(param))
|
||||
|
||||
self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0])
|
||||
self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1])
|
||||
|
||||
self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2])
|
||||
self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3])
|
||||
|
||||
class IncludeCoveredTest_01(IncludeCoveredTest):
|
||||
rule = 'include <foo>'
|
||||
|
||||
tests = [
|
||||
# rule equal strict equal covered covered exact
|
||||
('include <foo>' , [ True , True , True , True ]),
|
||||
('#include <foo>' , [ True , False , True , True ]),
|
||||
('include if exists <foo>' , [ False , False , True , True ]),
|
||||
('#include if exists <foo>' , [ False , False , True , True ]),
|
||||
('include <foobar>' , [ False , False , False , False ]),
|
||||
# ('include "foo"' , [ False , False , False , False ]), # disabled due to implementation restrictions, see re_match_include_parse()
|
||||
# ('include if exists "foo"' , [ False , False , False , False ]),
|
||||
]
|
||||
|
||||
class IncludeCoveredTest_02(IncludeCoveredTest):
|
||||
rule = 'include if exists <foo>'
|
||||
|
||||
tests = [
|
||||
# rule equal strict equal covered covered exact
|
||||
('include <foo>' , [ False , False , False , False ]),
|
||||
('#include <foo>' , [ False , False , False , False ]),
|
||||
('#include if exists <foo>' , [ True , False , True , True ]),
|
||||
('include <foobar>' , [ False , False , False , False ]),
|
||||
# ('include "foo"' , [ False , False , False , False ]), # disabled due to implementation restrictions, see re_match_include_parse()
|
||||
# ('include if exists "foo"' , [ False , False , False , False ]),
|
||||
]
|
||||
|
||||
#class IncludeCoveredTest_Invalid(AATest):
|
||||
# def test_borked_obj_is_covered_1(self):
|
||||
# obj = IncludeRule.parse('include <foo>')
|
||||
|
||||
# testobj = IncludeRule('foo', True, True)
|
||||
# testobj.path = ''
|
||||
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.is_covered(testobj)
|
||||
|
||||
# def test_borked_obj_is_covered_2(self):
|
||||
# obj = IncludeRule.parse('include send set=quit peer=/foo,')
|
||||
|
||||
# testobj = IncludeRule('send', 'quit', '/foo')
|
||||
# testobj.include = ''
|
||||
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.is_covered(testobj)
|
||||
|
||||
# def test_borked_obj_is_covered_3(self):
|
||||
# obj = IncludeRule.parse('include send set=quit peer=/foo,')
|
||||
|
||||
# testobj = IncludeRule('send', 'quit', '/foo')
|
||||
# testobj.peer = ''
|
||||
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.is_covered(testobj)
|
||||
|
||||
# def test_invalid_is_covered(self):
|
||||
# obj = IncludeRule.parse('include send,')
|
||||
|
||||
# testobj = BaseRule() # different type
|
||||
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.is_covered(testobj)
|
||||
|
||||
# def test_invalid_is_equal(self):
|
||||
# obj = IncludeRule.parse('include send,')
|
||||
|
||||
# testobj = BaseRule() # different type
|
||||
|
||||
# with self.assertRaises(AppArmorBug):
|
||||
# obj.is_equal(testobj)
|
||||
|
||||
class IncludeLogprofHeaderTest(AATest):
|
||||
# tests = [
|
||||
# ('include,', [ _('Access mode'), _('ALL'), _('Include'), _('ALL'), _('Peer'), _('ALL'), ]),
|
||||
# ('include send,', [ _('Access mode'), 'send', _('Include'), _('ALL'), _('Peer'), _('ALL'), ]),
|
||||
# ('include send set=quit,', [ _('Access mode'), 'send', _('Include'), 'quit', _('Peer'), _('ALL'), ]),
|
||||
# ('deny include,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Include'), _('ALL'), _('Peer'), _('ALL'), ]),
|
||||
# ('allow include send,', [_('Qualifier'), 'allow', _('Access mode'), 'send', _('Include'), _('ALL'), _('Peer'), _('ALL'), ]),
|
||||
# ('audit include send set=quit,', [_('Qualifier'), 'audit', _('Access mode'), 'send', _('Include'), 'quit', _('Peer'), _('ALL'), ]),
|
||||
# ('audit deny include send,', [_('Qualifier'), 'audit deny', _('Access mode'), 'send', _('Include'), _('ALL'), _('Peer'), _('ALL'), ]),
|
||||
# ('include set=(int, quit),', [ _('Access mode'), _('ALL'), _('Include'), 'int quit', _('Peer'), _('ALL'), ]),
|
||||
# ('include set=( quit, int),', [ _('Access mode'), _('ALL'), _('Include'), 'int quit', _('Peer'), _('ALL'), ]),
|
||||
# ('include (send, receive) set=( quit, int) peer=/foo,', [ _('Access mode'), 'receive send', _('Include'), 'int quit', _('Peer'), '/foo', ]),
|
||||
# ]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
obj = IncludeRule._parse(params)
|
||||
self.assertEqual(obj.logprof_header(), expected)
|
||||
|
||||
## --- tests for IncludeRuleset --- #
|
||||
|
||||
class IncludeRulesTest(AATest):
|
||||
def test_empty_ruleset(self):
|
||||
ruleset = IncludeRuleset()
|
||||
ruleset_2 = IncludeRuleset()
|
||||
self.assertEqual([], ruleset.get_raw(2))
|
||||
self.assertEqual([], ruleset.get_clean(2))
|
||||
self.assertEqual([], ruleset_2.get_raw(2))
|
||||
self.assertEqual([], ruleset_2.get_clean(2))
|
||||
|
||||
def test_ruleset_1(self):
|
||||
ruleset = IncludeRuleset()
|
||||
rules = [
|
||||
' include <foo> ',
|
||||
' #include "/bar" ',
|
||||
]
|
||||
|
||||
expected_raw = [
|
||||
'include <foo>',
|
||||
'#include "/bar"',
|
||||
'',
|
||||
]
|
||||
|
||||
expected_clean = [
|
||||
'include "/bar"',
|
||||
'include <foo>',
|
||||
'',
|
||||
]
|
||||
|
||||
for rule in rules:
|
||||
ruleset.add(IncludeRule.parse(rule))
|
||||
|
||||
self.assertEqual(expected_raw, ruleset.get_raw())
|
||||
self.assertEqual(expected_clean, ruleset.get_clean())
|
||||
|
||||
def test_ruleset_2(self):
|
||||
ruleset = IncludeRuleset()
|
||||
rules = [
|
||||
' include <foo> ',
|
||||
' #include "/bar" ',
|
||||
'#include if exists "/asdf" ',
|
||||
' include if exists <baz> ',
|
||||
]
|
||||
|
||||
expected_raw = [
|
||||
'include <foo>',
|
||||
'#include "/bar"',
|
||||
'#include if exists "/asdf"',
|
||||
'include if exists <baz>',
|
||||
'',
|
||||
]
|
||||
|
||||
expected_clean = [
|
||||
'include "/bar"',
|
||||
'include <foo>',
|
||||
'include if exists "/asdf"',
|
||||
'include if exists <baz>',
|
||||
'',
|
||||
]
|
||||
|
||||
for rule in rules:
|
||||
ruleset.add(IncludeRule.parse(rule))
|
||||
|
||||
self.assertEqual(expected_raw, ruleset.get_raw())
|
||||
self.assertEqual(expected_clean, ruleset.get_clean())
|
||||
|
||||
class IncludeGlobTestAATest(AATest):
|
||||
def setUp(self):
|
||||
self.maxDiff = None
|
||||
self.ruleset = IncludeRuleset()
|
||||
|
||||
# def test_glob(self):
|
||||
# with self.assertRaises(NotImplementedError):
|
||||
# # get_glob_ext is not available for include rules
|
||||
# self.ruleset.get_glob('include send set=int,')
|
||||
|
||||
def test_glob_ext(self):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
# get_glob_ext is not available for include rules
|
||||
self.ruleset.get_glob_ext('include send set=int,')
|
||||
|
||||
#class IncludeDeleteTestAATest(AATest):
|
||||
# pass
|
||||
|
||||
setup_all_loops(__name__)
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=1)
|
Loading…
x
Reference in New Issue
Block a user