From 325e30a85d482b649cddd060f17432925027fe66 Mon Sep 17 00:00:00 2001 From: Etienne Stalmans Date: Wed, 2 Oct 2024 13:05:31 +0200 Subject: [PATCH] extend filtering to cover tuple and dict arguments for logging --- realtime/_async/client.py | 2 +- realtime/logging_util.py | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/realtime/_async/client.py b/realtime/_async/client.py index 81314a2..f499826 100644 --- a/realtime/_async/client.py +++ b/realtime/_async/client.py @@ -125,7 +125,7 @@ async def connect(self) -> None: while retries < self.max_retries: try: - self.ws_connection = await websockets.connect(self.url) + self.ws_connection = await websockets.connect(self.url, logger=logger) if self.ws_connection.open: logger.info("Connection was successful") return await self._on_connect() diff --git a/realtime/logging_util.py b/realtime/logging_util.py index 5f50087..cf04c30 100644 --- a/realtime/logging_util.py +++ b/realtime/logging_util.py @@ -1,3 +1,4 @@ +import copy import logging import re @@ -8,17 +9,35 @@ redact = r"(eyJh[-_\w]*\.)([-_\w]*)\." +def gred(g): + """Redact the payload of the JWT, keeping the header and signature""" + return f"{g.group(1)}REDACTED." if len(g.groups()) > 1 else g + + class TokenMaskingFilter(logging.Filter): """Mask access_tokens in logs""" def filter(self, record): record.msg = self.sanitize_line(record.msg) + record.args = self.sanitize_args(record.args) return True @staticmethod - def sanitize_line(line): - def gred(g): - """Redact the payload of the JWT, keeping the header and signature""" - return f"{g.group(1)}REDACTED." if len(g.groups()) > 1 else g + def sanitize_args(d): + if isinstance(d, dict): + d = d.copy() # so we don't overwrite anything + for k, v in d.items(): + d[k] = self.sanitize_line(v) + elif isinstance(d, tuple): + # need a deepcopy of tuple turned to a list, as to not change the original values + # otherwise we end up changing the items at the original memory location of the passed in tuple + y = copy.deepcopy(list(d)) + for x, value in enumerate(y): + if isinstance(value, str): + y[x] = re.sub(redact, gred, value) + return tuple(y) # convert the list back to a tuple + return d + @staticmethod + def sanitize_line(line): return re.sub(redact, gred, line)