mirror of https://github.com/fail2ban/fail2ban
fixes issue with wrong-chars in string items of CallingMap by its representation, additionally don't calculate values implicitly (may be unexpected for some constellations resp. too slow in DEBUG)
parent
2f5059ebfb
commit
79350e916e
|
@ -83,6 +83,8 @@ class CallingMap(MutableMapping, object):
|
||||||
The dictionary data which can be accessed to obtain items uncalled
|
The dictionary data which can be accessed to obtain items uncalled
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
CM_REPR_ITEMS = ()
|
||||||
|
|
||||||
# immutable=True saves content between actions, without interim copying (save original on demand, recoverable via reset)
|
# immutable=True saves content between actions, without interim copying (save original on demand, recoverable via reset)
|
||||||
__slots__ = ('data', 'storage', 'immutable', '__org_data')
|
__slots__ = ('data', 'storage', 'immutable', '__org_data')
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -98,14 +100,29 @@ class CallingMap(MutableMapping, object):
|
||||||
pass
|
pass
|
||||||
self.immutable = immutable
|
self.immutable = immutable
|
||||||
|
|
||||||
def __repr__(self):
|
def _asrepr(self, calculated=False):
|
||||||
return "%s(%r)" % (self.__class__.__name__, self._asdict())
|
# be sure it is suitable as string, so use str as checker:
|
||||||
|
return "%s(%r)" % (self.__class__.__name__, self._asdict(calculated, str))
|
||||||
|
|
||||||
def _asdict(self):
|
__repr__ = _asrepr
|
||||||
|
|
||||||
|
def _asdict(self, calculated=False, checker=None):
|
||||||
|
d = dict(self.data, **self.storage)
|
||||||
|
if not calculated:
|
||||||
|
return dict((n,v) for n,v in d.iteritems() \
|
||||||
|
if not callable(v) or n in self.CM_REPR_ITEMS)
|
||||||
|
for n,v in d.items():
|
||||||
|
if callable(v):
|
||||||
try:
|
try:
|
||||||
return dict(self)
|
# calculate:
|
||||||
except:
|
v = self.__getitem__(n)
|
||||||
return dict(self.data, **self.storage)
|
# convert if needed:
|
||||||
|
if checker: checker(v)
|
||||||
|
# store calculated:
|
||||||
|
d[n] = v
|
||||||
|
except: # can't calculate - just ignore it
|
||||||
|
pass
|
||||||
|
return d
|
||||||
|
|
||||||
def getRawItem(self, key):
|
def getRawItem(self, key):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -290,6 +290,8 @@ class Actions(JailThread, Mapping):
|
||||||
|
|
||||||
class ActionInfo(CallingMap):
|
class ActionInfo(CallingMap):
|
||||||
|
|
||||||
|
CM_REPR_ITEMS = ("fid", "raw-ticket")
|
||||||
|
|
||||||
AI_DICT = {
|
AI_DICT = {
|
||||||
"ip": lambda self: self.__ticket.getIP(),
|
"ip": lambda self: self.__ticket.getIP(),
|
||||||
"family": lambda self: self['ip'].familyStr,
|
"family": lambda self: self['ip'].familyStr,
|
||||||
|
@ -307,7 +309,9 @@ class Actions(JailThread, Mapping):
|
||||||
"ipmatches": lambda self: "\n".join(self._mi4ip(True).getMatches()),
|
"ipmatches": lambda self: "\n".join(self._mi4ip(True).getMatches()),
|
||||||
"ipjailmatches": lambda self: "\n".join(self._mi4ip().getMatches()),
|
"ipjailmatches": lambda self: "\n".join(self._mi4ip().getMatches()),
|
||||||
"ipfailures": lambda self: self._mi4ip(True).getAttempt(),
|
"ipfailures": lambda self: self._mi4ip(True).getAttempt(),
|
||||||
"ipjailfailures": lambda self: self._mi4ip().getAttempt()
|
"ipjailfailures": lambda self: self._mi4ip().getAttempt(),
|
||||||
|
# raw ticket info:
|
||||||
|
"raw-ticket": lambda self: repr(self.__ticket)
|
||||||
}
|
}
|
||||||
|
|
||||||
__slots__ = CallingMap.__slots__ + ('__ticket', '__jail', '__mi4ip')
|
__slots__ = CallingMap.__slots__ + ('__ticket', '__jail', '__mi4ip')
|
||||||
|
|
|
@ -567,13 +567,18 @@ class CommandActionTest(LogCaptureTestCase):
|
||||||
'b': lambda self: self['a'] + 6,
|
'b': lambda self: self['a'] + 6,
|
||||||
'c': ''
|
'c': ''
|
||||||
})
|
})
|
||||||
s = repr(m)
|
s = repr(m); # only stored values (no calculated)
|
||||||
|
self.assertNotIn("'a': ", s)
|
||||||
|
self.assertNotIn("'b': ", s)
|
||||||
|
self.assertIn("'c': ''", s)
|
||||||
|
|
||||||
|
s = m._asrepr(True) # all values (including calculated)
|
||||||
self.assertIn("'a': 5", s)
|
self.assertIn("'a': 5", s)
|
||||||
self.assertIn("'b': 11", s)
|
self.assertIn("'b': 11", s)
|
||||||
self.assertIn("'c': ''", s)
|
self.assertIn("'c': ''", s)
|
||||||
|
|
||||||
m['c'] = lambda self: self['xxx'] + 7; # unresolvable
|
m['c'] = lambda self: self['xxx'] + 7; # unresolvable
|
||||||
s = repr(m)
|
s = m._asrepr(True)
|
||||||
self.assertIn("'a': 5", s)
|
self.assertIn("'a': 5", s)
|
||||||
self.assertIn("'b': 11", s)
|
self.assertIn("'b': 11", s)
|
||||||
self.assertIn("'c': ", s) # presents as callable
|
self.assertIn("'c': ", s) # presents as callable
|
||||||
|
|
Loading…
Reference in New Issue