Some default cleanup of contrib, pep8 adjustments

This commit is contained in:
Griatch 2018-09-29 15:13:06 +02:00
parent 85114d6de5
commit a8eecce989
4 changed files with 118 additions and 103 deletions

View file

@ -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 = []
]

View file

@ -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.

View file

@ -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)

View file

@ -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):