diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index bf7b49f1..adda3782 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -155,10 +155,19 @@ Mask Sensitive Information in Logs

- Enable to mask passwords, access tokens, and public IP addresses with asterisks (*) in the logs.
+ Enable to mask passwords, access tokens, and public IP addresses, and email addresses with asterisks (*) in the logs.
Note: Only logs from the time this setting is enabled will be masked. Do not post your logs publically without masking sensitive information!

+
+ +

+ Enable to mask Plex usernames and Tautulli friendly names with asterisks (*) in the logs.
+ Note: Only logs from the time this setting is enabled will be masked. +

+

History Logging

diff --git a/plexpy/config.py b/plexpy/config.py index 77034bf5..c296d628 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -148,6 +148,7 @@ _CONFIG_DEFINITIONS = { 'LAUNCH_BROWSER': (int, 'General', 1), 'LAUNCH_STARTUP': (int, 'General', 1), 'LOG_BLACKLIST': (int, 'General', 1), + 'LOG_BLACKLIST_USERNAMES': (int, 'General', 1), 'LOG_DIR': (str, 'General', ''), 'LOGGING_IGNORE_INTERVAL': (int, 'Monitoring', 120), 'METADATA_CACHE_SECONDS': (int, 'Advanced', 1800), @@ -315,6 +316,7 @@ CHECKED_SETTINGS = [ 'LAUNCH_BROWSER', 'LAUNCH_STARTUP', 'LOG_BLACKLIST', + 'LOG_BLACKLIST_USERNAMES', 'MONITOR_PMS_UPDATES', 'MUSICBRAINZ_LOOKUP', 'NEWSLETTER_INLINE_STYLES', diff --git a/plexpy/logger.py b/plexpy/logger.py index a4064dc6..e09ad52d 100644 --- a/plexpy/logger.py +++ b/plexpy/logger.py @@ -31,9 +31,10 @@ import traceback import plexpy if plexpy.PYTHON2: import helpers + import users from config import _BLACKLIST_KEYS, _WHITELIST_KEYS else: - from plexpy import helpers + from plexpy import helpers, users from plexpy.config import _BLACKLIST_KEYS, _WHITELIST_KEYS @@ -88,9 +89,6 @@ class BlacklistFilter(logging.Filter): """ Log filter for blacklisted tokens and passwords """ - def __init__(self): - super(BlacklistFilter, self).__init__() - def filter(self, record): if not plexpy.CONFIG.LOG_BLACKLIST: return True @@ -117,15 +115,46 @@ class BlacklistFilter(logging.Filter): return True +class UsernameFilter(logging.Filter): + """ + Log filter for usernames + """ + def filter(self, record): + if not plexpy.CONFIG.LOG_BLACKLIST_USERNAMES: + return True + + for item in users.Users().get_users(): + username = item['username'] + friendly_name = item['friendly_name'] + + try: + record.msg = self.replace(record.msg, username) + record.msg = self.replace(record.msg, friendly_name) + + args = [] + for arg in record.args: + if isinstance(arg, str): + arg = self.replace(arg, username) + arg = self.replace(arg, friendly_name) + args.append(arg) + record.args = tuple(args) + except: + pass + + return True + + @staticmethod + def replace(text, match): + mask = match[:2] + 8 * '*' + match[-1] + return re.sub(r'\b{}\b'.format(match), mask, text, flags=re.IGNORECASE) + + class RegexFilter(logging.Filter): """ Base class for regex log filter """ REGEX = re.compile(r'') - def __init__(self): - super(RegexFilter, self).__init__() - def filter(self, record): if not plexpy.CONFIG.LOG_BLACKLIST: return True @@ -179,14 +208,14 @@ class EmailFilter(RegexFilter): Log filter for email addresses """ REGEX = re.compile( - r'([a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@' - r'(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)', + r'([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)', re.IGNORECASE ) def replace(self, text, email): email_parts = email.partition('@') - return text.replace(email, 16 * '*' + email_parts[1] + 8 * '*') + mask = email_parts[0][:2] + 8 * '*' + email_parts[0][-1] + email_parts[1] + 8 * '*' + return text.replace(email, mask) class PlexTokenFilter(RegexFilter): @@ -289,6 +318,7 @@ def initLogger(console=False, log_dir=False, verbose=False): logger_plex_websocket.handlers + \ cherrypy.log.error_log.handlers for handler in log_handlers: + handler.addFilter(UsernameFilter()) handler.addFilter(BlacklistFilter()) handler.addFilter(PublicIPFilter()) handler.addFilter(EmailFilter())