mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-30 03:28:31 -07:00
Add setting to mask usernames in logs
This commit is contained in:
parent
2331c76326
commit
113043d9bc
3 changed files with 52 additions and 11 deletions
|
@ -155,10 +155,19 @@
|
||||||
<input type="checkbox" id="log_blacklist" name="log_blacklist" value="1" ${config['log_blacklist']}> Mask Sensitive Information in Logs
|
<input type="checkbox" id="log_blacklist" name="log_blacklist" value="1" ${config['log_blacklist']}> Mask Sensitive Information in Logs
|
||||||
</label>
|
</label>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Enable to mask passwords, access tokens, and public IP addresses with asterisks (*) in the logs.<br />
|
Enable to mask passwords, access tokens, and public IP addresses, and email addresses with asterisks (*) in the logs.<br />
|
||||||
Note: Only logs from the time this setting is enabled will be masked. Do not post your logs publically without masking sensitive information!
|
Note: Only logs from the time this setting is enabled will be masked. Do not post your logs publically without masking sensitive information!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox advanced-setting">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="log_blacklist_usernames" name="log_blacklist_usernames" value="1" ${config['log_blacklist_usernames']}> Mask Usernames in Logs
|
||||||
|
</label>
|
||||||
|
<p class="help-block">
|
||||||
|
Enable to mask Plex usernames and Tautulli friendly names with asterisks (*) in the logs.<br />
|
||||||
|
Note: Only logs from the time this setting is enabled will be masked.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="padded-header">
|
<div class="padded-header">
|
||||||
<h3>History Logging</h3>
|
<h3>History Logging</h3>
|
||||||
|
|
|
@ -148,6 +148,7 @@ _CONFIG_DEFINITIONS = {
|
||||||
'LAUNCH_BROWSER': (int, 'General', 1),
|
'LAUNCH_BROWSER': (int, 'General', 1),
|
||||||
'LAUNCH_STARTUP': (int, 'General', 1),
|
'LAUNCH_STARTUP': (int, 'General', 1),
|
||||||
'LOG_BLACKLIST': (int, 'General', 1),
|
'LOG_BLACKLIST': (int, 'General', 1),
|
||||||
|
'LOG_BLACKLIST_USERNAMES': (int, 'General', 1),
|
||||||
'LOG_DIR': (str, 'General', ''),
|
'LOG_DIR': (str, 'General', ''),
|
||||||
'LOGGING_IGNORE_INTERVAL': (int, 'Monitoring', 120),
|
'LOGGING_IGNORE_INTERVAL': (int, 'Monitoring', 120),
|
||||||
'METADATA_CACHE_SECONDS': (int, 'Advanced', 1800),
|
'METADATA_CACHE_SECONDS': (int, 'Advanced', 1800),
|
||||||
|
@ -315,6 +316,7 @@ CHECKED_SETTINGS = [
|
||||||
'LAUNCH_BROWSER',
|
'LAUNCH_BROWSER',
|
||||||
'LAUNCH_STARTUP',
|
'LAUNCH_STARTUP',
|
||||||
'LOG_BLACKLIST',
|
'LOG_BLACKLIST',
|
||||||
|
'LOG_BLACKLIST_USERNAMES',
|
||||||
'MONITOR_PMS_UPDATES',
|
'MONITOR_PMS_UPDATES',
|
||||||
'MUSICBRAINZ_LOOKUP',
|
'MUSICBRAINZ_LOOKUP',
|
||||||
'NEWSLETTER_INLINE_STYLES',
|
'NEWSLETTER_INLINE_STYLES',
|
||||||
|
|
|
@ -31,9 +31,10 @@ import traceback
|
||||||
import plexpy
|
import plexpy
|
||||||
if plexpy.PYTHON2:
|
if plexpy.PYTHON2:
|
||||||
import helpers
|
import helpers
|
||||||
|
import users
|
||||||
from config import _BLACKLIST_KEYS, _WHITELIST_KEYS
|
from config import _BLACKLIST_KEYS, _WHITELIST_KEYS
|
||||||
else:
|
else:
|
||||||
from plexpy import helpers
|
from plexpy import helpers, users
|
||||||
from plexpy.config import _BLACKLIST_KEYS, _WHITELIST_KEYS
|
from plexpy.config import _BLACKLIST_KEYS, _WHITELIST_KEYS
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,9 +89,6 @@ class BlacklistFilter(logging.Filter):
|
||||||
"""
|
"""
|
||||||
Log filter for blacklisted tokens and passwords
|
Log filter for blacklisted tokens and passwords
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
|
||||||
super(BlacklistFilter, self).__init__()
|
|
||||||
|
|
||||||
def filter(self, record):
|
def filter(self, record):
|
||||||
if not plexpy.CONFIG.LOG_BLACKLIST:
|
if not plexpy.CONFIG.LOG_BLACKLIST:
|
||||||
return True
|
return True
|
||||||
|
@ -117,15 +115,46 @@ class BlacklistFilter(logging.Filter):
|
||||||
return True
|
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):
|
class RegexFilter(logging.Filter):
|
||||||
"""
|
"""
|
||||||
Base class for regex log filter
|
Base class for regex log filter
|
||||||
"""
|
"""
|
||||||
REGEX = re.compile(r'')
|
REGEX = re.compile(r'')
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(RegexFilter, self).__init__()
|
|
||||||
|
|
||||||
def filter(self, record):
|
def filter(self, record):
|
||||||
if not plexpy.CONFIG.LOG_BLACKLIST:
|
if not plexpy.CONFIG.LOG_BLACKLIST:
|
||||||
return True
|
return True
|
||||||
|
@ -179,14 +208,14 @@ class EmailFilter(RegexFilter):
|
||||||
Log filter for email addresses
|
Log filter for email addresses
|
||||||
"""
|
"""
|
||||||
REGEX = re.compile(
|
REGEX = re.compile(
|
||||||
r'([a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@'
|
r'([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)',
|
||||||
r'(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)',
|
|
||||||
re.IGNORECASE
|
re.IGNORECASE
|
||||||
)
|
)
|
||||||
|
|
||||||
def replace(self, text, email):
|
def replace(self, text, email):
|
||||||
email_parts = email.partition('@')
|
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):
|
class PlexTokenFilter(RegexFilter):
|
||||||
|
@ -289,6 +318,7 @@ def initLogger(console=False, log_dir=False, verbose=False):
|
||||||
logger_plex_websocket.handlers + \
|
logger_plex_websocket.handlers + \
|
||||||
cherrypy.log.error_log.handlers
|
cherrypy.log.error_log.handlers
|
||||||
for handler in log_handlers:
|
for handler in log_handlers:
|
||||||
|
handler.addFilter(UsernameFilter())
|
||||||
handler.addFilter(BlacklistFilter())
|
handler.addFilter(BlacklistFilter())
|
||||||
handler.addFilter(PublicIPFilter())
|
handler.addFilter(PublicIPFilter())
|
||||||
handler.addFilter(EmailFilter())
|
handler.addFilter(EmailFilter())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue