Some default cleanup of contrib, pep8 adjustments
This commit is contained in:
parent
85114d6de5
commit
a8eecce989
4 changed files with 118 additions and 103 deletions
|
|
@ -30,38 +30,43 @@ Files included in this module:
|
||||||
|
|
||||||
Installation/Configuration:
|
Installation/Configuration:
|
||||||
|
|
||||||
Deployment is completed by configuring a few settings in server.conf. In short,
|
Deployment is completed by configuring a few settings in server.conf. This line
|
||||||
you must tell Evennia to use this ServerSession instead of its own, specify
|
is required:
|
||||||
which direction(s) you wish to record and where you want the data sent.
|
|
||||||
|
|
||||||
SERVER_SESSION_CLASS = 'evennia.contrib.auditing.server.AuditedServerSession'
|
SERVER_SESSION_CLASS = 'evennia.contrib.auditing.server.AuditedServerSession'
|
||||||
|
|
||||||
|
This tells Evennia to use this ServerSession instead of its own. Below are the
|
||||||
|
other possible options along with the default value that will be used if unset.
|
||||||
|
|
||||||
# Where to send logs? Define the path to a module containing your callback
|
# Where to send logs? Define the path to a module containing your callback
|
||||||
# function. It should take a single dict argument as input.
|
# function. It should take a single dict argument as input
|
||||||
AUDIT_CALLBACK = 'evennia.contrib.auditing.outputs.to_file'
|
AUDIT_CALLBACK = 'evennia.contrib.auditing.outputs.to_file'
|
||||||
|
|
||||||
# Log user input? Be ethical about this; it will log all private and
|
# Log user input? Be ethical about this; it will log all private and
|
||||||
# public communications between players and/or admins.
|
# public communications between players and/or admins (default: False).
|
||||||
AUDIT_IN = True/False
|
AUDIT_IN = False
|
||||||
|
|
||||||
# Log server output? This will result in logging of ALL system
|
# Log server output? This will result in logging of ALL system
|
||||||
# messages and ALL broadcasts to connected players, so on a busy game any
|
# messages and ALL broadcasts to connected players, so on a busy game any
|
||||||
# broadcast to all users will yield a single event for every connected user!
|
# broadcast to all users will yield a single event for every connected user!
|
||||||
AUDIT_OUT = True/False
|
AUDIT_OUT = False
|
||||||
|
|
||||||
# The default output is a dict. Do you want to allow key:value pairs with
|
# The default output is a dict. Do you want to allow key:value pairs with
|
||||||
# null/blank values? If you're just writing to disk, disabling this saves
|
# null/blank values? If you're just writing to disk, disabling this saves
|
||||||
# some disk space, but whether you *want* sparse values or not is more of a
|
# some disk space, but whether you *want* sparse values or not is more of a
|
||||||
# consideration if you're shipping logs to a NoSQL/schemaless database.
|
# consideration if you're shipping logs to a NoSQL/schemaless database.
|
||||||
AUDIT_ALLOW_SPARSE = True/False
|
# (default: False)
|
||||||
|
AUDIT_ALLOW_SPARSE = False
|
||||||
|
|
||||||
# If you write custom commands that handle sensitive data like passwords,
|
# If you write custom commands that handle sensitive data like passwords,
|
||||||
# you must write a regular expression to remove that before writing to log.
|
# you must write a regular expression to remove that before writing to log.
|
||||||
# AUDIT_MASKS is a list of dictionaries that define the names of commands
|
# AUDIT_MASKS is a list of dictionaries that define the names of commands
|
||||||
# and the regexes needed to scrub them.
|
# and the regexes needed to scrub them.
|
||||||
|
# The system already has defaults to filter out sensitive login/creation
|
||||||
|
# commands in the default command set. Your list of AUDIT_MASKS will be appended
|
||||||
|
# to those defaults.
|
||||||
#
|
#
|
||||||
# The sensitive data itself must be captured in a named group with a
|
# In the regex, the sensitive data itself must be captured in a named group with a
|
||||||
# label of 'secret'.
|
# label of 'secret' (see the Python docs on the `re` module for more info). For
|
||||||
AUDIT_MASKS = [
|
# example: `{'authentication': r"^@auth\s+(?P<secret>[\w]+)"}`
|
||||||
{'authentication': r"^@auth\s+(?P<secret>[\w]+)"},
|
AUDIT_MASKS = []
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from evennia.utils.logger import log_file
|
||||||
import json
|
import json
|
||||||
import syslog
|
import syslog
|
||||||
|
|
||||||
|
|
||||||
def to_file(data):
|
def to_file(data):
|
||||||
"""
|
"""
|
||||||
Writes dictionaries of data generated by an AuditedServerSession to files
|
Writes dictionaries of data generated by an AuditedServerSession to files
|
||||||
|
|
@ -35,6 +36,7 @@ def to_file(data):
|
||||||
# Write it
|
# Write it
|
||||||
log_file(json.dumps(data), filename="audit_%s.log" % bucket)
|
log_file(json.dumps(data), filename="audit_%s.log" % bucket)
|
||||||
|
|
||||||
|
|
||||||
def to_syslog(data):
|
def to_syslog(data):
|
||||||
"""
|
"""
|
||||||
Writes dictionaries of data generated by an AuditedServerSession to syslog.
|
Writes dictionaries of data generated by an AuditedServerSession to syslog.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ from evennia.utils import utils, logger, mod_import, get_evennia_version
|
||||||
from evennia.server.serversession import ServerSession
|
from evennia.server.serversession import ServerSession
|
||||||
|
|
||||||
# Attributes governing auditing of commands and where to send log objects
|
# Attributes governing auditing of commands and where to send log objects
|
||||||
AUDIT_CALLBACK = getattr(ev_settings, 'AUDIT_CALLBACK', None)
|
AUDIT_CALLBACK = getattr(ev_settings, 'AUDIT_CALLBACK',
|
||||||
|
'evennia.contrib.auditing.outputs.to_file')
|
||||||
AUDIT_IN = getattr(ev_settings, 'AUDIT_IN', False)
|
AUDIT_IN = getattr(ev_settings, 'AUDIT_IN', False)
|
||||||
AUDIT_OUT = getattr(ev_settings, 'AUDIT_OUT', False)
|
AUDIT_OUT = getattr(ev_settings, 'AUDIT_OUT', False)
|
||||||
AUDIT_ALLOW_SPARSE = getattr(ev_settings, 'AUDIT_ALLOW_SPARSE', False)
|
AUDIT_ALLOW_SPARSE = getattr(ev_settings, 'AUDIT_ALLOW_SPARSE', False)
|
||||||
|
|
@ -30,17 +31,19 @@ AUDIT_MASKS = [
|
||||||
{'password': r"^[@\s]*[password]{6,9}\s+(?P<secret>.*)"},
|
{'password': r"^[@\s]*[password]{6,9}\s+(?P<secret>.*)"},
|
||||||
] + getattr(ev_settings, 'AUDIT_MASKS', [])
|
] + getattr(ev_settings, 'AUDIT_MASKS', [])
|
||||||
|
|
||||||
|
|
||||||
if AUDIT_CALLBACK:
|
if AUDIT_CALLBACK:
|
||||||
try:
|
try:
|
||||||
AUDIT_CALLBACK = getattr(mod_import('.'.join(AUDIT_CALLBACK.split('.')[:-1])), AUDIT_CALLBACK.split('.')[-1])
|
AUDIT_CALLBACK = getattr(
|
||||||
logger.log_info("Auditing module online.")
|
mod_import('.'.join(AUDIT_CALLBACK.split('.')[:-1])), AUDIT_CALLBACK.split('.')[-1])
|
||||||
logger.log_info("Recording user input: %s" % AUDIT_IN)
|
logger.log_sec("Auditing module online.")
|
||||||
logger.log_info("Recording server output: %s" % AUDIT_OUT)
|
logger.log_sec("Audit record User input: {}, output: {}.\n"
|
||||||
logger.log_info("Recording sparse values: %s" % AUDIT_ALLOW_SPARSE)
|
"Audit sparse recording: {}, Log callback: {}".format(
|
||||||
logger.log_info("Log callback destination: %s" % AUDIT_CALLBACK)
|
AUDIT_IN, AUDIT_OUT, AUDIT_ALLOW_SPARSE, AUDIT_CALLBACK))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.log_err("Failed to activate Auditing module. %s" % e)
|
logger.log_err("Failed to activate Auditing module. %s" % e)
|
||||||
|
|
||||||
|
|
||||||
class AuditedServerSession(ServerSession):
|
class AuditedServerSession(ServerSession):
|
||||||
"""
|
"""
|
||||||
This particular implementation parses all server inputs and/or outputs and
|
This particular implementation parses all server inputs and/or outputs and
|
||||||
|
|
@ -80,7 +83,8 @@ class AuditedServerSession(ServerSession):
|
||||||
bytecount = 0
|
bytecount = 0
|
||||||
|
|
||||||
# Do not log empty lines
|
# Do not log empty lines
|
||||||
if not kwargs: return {}
|
if not kwargs:
|
||||||
|
return {}
|
||||||
|
|
||||||
# Get current session's IP address
|
# Get current session's IP address
|
||||||
client_ip = session.address
|
client_ip = session.address
|
||||||
|
|
@ -106,7 +110,8 @@ class AuditedServerSession(ServerSession):
|
||||||
|
|
||||||
# Try to compile an input/output string
|
# Try to compile an input/output string
|
||||||
def drill(obj, bucket):
|
def drill(obj, bucket):
|
||||||
if isinstance(obj, dict): return bucket
|
if isinstance(obj, dict):
|
||||||
|
return bucket
|
||||||
elif utils.is_iter(obj):
|
elif utils.is_iter(obj):
|
||||||
for sub_obj in obj:
|
for sub_obj in obj:
|
||||||
bucket.extend(drill(sub_obj, []))
|
bucket.extend(drill(sub_obj, []))
|
||||||
|
|
@ -149,7 +154,7 @@ class AuditedServerSession(ServerSession):
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove any keys with blank values
|
# Remove any keys with blank values
|
||||||
if AUDIT_ALLOW_SPARSE == False:
|
if AUDIT_ALLOW_SPARSE is False:
|
||||||
log['data'] = {k: v for k, v in log['data'].iteritems() if v}
|
log['data'] = {k: v for k, v in log['data'].iteritems() if v}
|
||||||
log['objects'] = {k: v for k, v in log['objects'].iteritems() if v}
|
log['objects'] = {k: v for k, v in log['objects'].iteritems() if v}
|
||||||
log = {k: v for k, v in log.iteritems() if v}
|
log = {k: v for k, v in log.iteritems() if v}
|
||||||
|
|
@ -192,7 +197,8 @@ class AuditedServerSession(ServerSession):
|
||||||
|
|
||||||
if is_embedded:
|
if is_embedded:
|
||||||
msg = re.sub(submsg, '%s <Masked: %s>' % (masked, command), _msg, flags=re.IGNORECASE)
|
msg = re.sub(submsg, '%s <Masked: %s>' % (masked, command), _msg, flags=re.IGNORECASE)
|
||||||
else: msg = masked
|
else:
|
||||||
|
msg = masked
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
@ -209,7 +215,8 @@ class AuditedServerSession(ServerSession):
|
||||||
if AUDIT_CALLBACK and AUDIT_OUT:
|
if AUDIT_CALLBACK and AUDIT_OUT:
|
||||||
try:
|
try:
|
||||||
log = self.audit(src='server', **kwargs)
|
log = self.audit(src='server', **kwargs)
|
||||||
if log: AUDIT_CALLBACK(log)
|
if log:
|
||||||
|
AUDIT_CALLBACK(log)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.log_err(e)
|
logger.log_err(e)
|
||||||
|
|
||||||
|
|
@ -226,7 +233,8 @@ class AuditedServerSession(ServerSession):
|
||||||
if AUDIT_CALLBACK and AUDIT_IN:
|
if AUDIT_CALLBACK and AUDIT_IN:
|
||||||
try:
|
try:
|
||||||
log = self.audit(src='client', **kwargs)
|
log = self.audit(src='client', **kwargs)
|
||||||
if log: AUDIT_CALLBACK(log)
|
if log:
|
||||||
|
AUDIT_CALLBACK(log)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.log_err(e)
|
logger.log_err(e)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ Module containing the test cases for the Audit system.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from evennia.contrib.auditing.server import AuditedServerSession
|
|
||||||
from evennia.utils.test_resources import EvenniaTest
|
from evennia.utils.test_resources import EvenniaTest
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
@ -16,6 +15,7 @@ settings.AUDIT_ALLOW_SPARSE = True
|
||||||
# Configure settings to use custom session
|
# Configure settings to use custom session
|
||||||
settings.SERVER_SESSION_CLASS = "evennia.contrib.auditing.server.AuditedServerSession"
|
settings.SERVER_SESSION_CLASS = "evennia.contrib.auditing.server.AuditedServerSession"
|
||||||
|
|
||||||
|
|
||||||
class AuditingTest(EvenniaTest):
|
class AuditingTest(EvenniaTest):
|
||||||
|
|
||||||
def test_mask(self):
|
def test_mask(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue