Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding of redaction #4

Merged
merged 5 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ jobs:
pytest tests/test_redacting_entire_body.py
pytest tests/test_dont_redact_single_key.py
pytest tests/test_ignored_domains.py
pytest tests/test_ignore_redaction.py
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.0.17
current_version = 1.0.20
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name='supergood',
version='1.0.17',
version='1.0.20',
author='Alex Klarfeld',
description='The Python client for Supergood',
long_description=long_description,
Expand Down
8 changes: 4 additions & 4 deletions src/supergood/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ def _cache_request(self, request_id, url, method, body, headers):
'id': request_id,
'method': method,
'url': url,
'body': redact_values(safe_parse_json(body), self.config['includedKeys']),
'headers': redact_values(dict(headers), self.config['includedKeys']),
'body': redact_values(safe_parse_json(body), self.config['includedKeys'], self.config['ignoreRedaction']),
'headers': redact_values(dict(headers), self.config['includedKeys'], self.config['ignoreRedaction']),
'path': parsed_url.path,
'search': parsed_url.query,
'requestedAt': now,
Expand Down Expand Up @@ -126,8 +126,8 @@ def _cache_response(
decoded_body = safe_decode(response_body)
if(request):
response = {
'body': redact_values(safe_parse_json(decoded_body), self.config['includedKeys']),
'headers': redact_values(dict(response_headers), self.config['includedKeys']),
'body': redact_values(safe_parse_json(decoded_body), self.config['includedKeys'], self.config['ignoreRedaction']),
'headers': redact_values(dict(response_headers), self.config['includedKeys'], self.config['ignoreRedaction']),
'status': response_status,
'statusText': response_status_text,
'respondedAt': datetime.now().isoformat(),
Expand Down
3 changes: 2 additions & 1 deletion src/supergood/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
'eventSinkEndpoint': '/events',
'errorSinkEndpoint': '/errors',
'includedKeys': [],
'ignoredDomains': []
'ignoredDomains': [],
'ignoreRedaction': False,
}

ERRORS = {
Expand Down
9 changes: 6 additions & 3 deletions src/supergood/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def hash_value(input):
hash.update(encoded)
return b64encode(hash.digest()).decode('utf-8')

def redact_values(input, included_keys, byte_limit=DEFAULT_SUPERGOOD_BYTE_LIMIT):
def redact_values(input, included_keys, ignore_redaction=False, byte_limit=DEFAULT_SUPERGOOD_BYTE_LIMIT):
_input = input

payload = get(_input, 'response.body')
Expand All @@ -38,13 +38,16 @@ def redact_values(input, included_keys, byte_limit=DEFAULT_SUPERGOOD_BYTE_LIMIT)
if not _input:
return ''

if ignore_redaction:
return _input

if isinstance(_input, list):
for i, ele in enumerate(_input):
_input[i] = redact_values(ele, included_keys, byte_limit)
_input[i] = redact_values(ele, included_keys, ignore_redaction, byte_limit)
elif isinstance(_input, dict):
for key in _input.keys():
if key not in included_keys:
_input[key] = redact_values(_input[key], included_keys, byte_limit)
_input[key] = redact_values(_input[key], included_keys, ignore_redaction, byte_limit)
elif isinstance(_input, bool):
_input = False
elif isinstance(_input, str):
Expand Down
5 changes: 3 additions & 2 deletions tests/helper.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
def get_config(flush_interval=30000, included_keys=[], ignored_domains=[]):
def get_config(flush_interval=30000, included_keys=[], ignored_domains=[], ignore_redaction=False):
return {
'flushInterval': flush_interval,
'eventSinkEndpoint': 'https://api.supergood.ai/events',
'errorSinkEndpoint': 'https://api.supergood.ai/errors',
'includedKeys': included_keys,
'ignoredDomains': ignored_domains
'ignoredDomains': ignored_domains,
'ignoreRedaction': ignore_redaction
}
26 changes: 26 additions & 0 deletions tests/test_ignore_redaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import requests
import re
import pytest
from unittest.mock import patch, Mock

from pytest_httpserver import HTTPServer
from .helper import get_config
from supergood import Client
from supergood.api import Api

def test_ignore_redaction(httpserver: HTTPServer, mocker):
config = get_config(ignore_redaction=True)
mocker.patch('supergood.api.Api.post_events', return_value=None)
mocker.patch('supergood.api.Api.post_errors', return_value=None)
supergood_client = Client(config=config)
httpserver.expect_request('/200').respond_with_json({ 'string': 'abc', 'number': 123, 'float': 123.45, 'bool': True, 'complex_string': 'Alex Klarfeld 911!'})
requests.get(httpserver.url_for('/200'))
supergood_client.flush_cache()
supergood_client.kill()
args = Api.post_events.call_args[0][0]
body = args[0]['response']['body']
assert body['string'] == 'abc'
assert body['number'] == 123
assert body['float'] == 123.45
assert body['bool'] == True
assert body['complex_string'] == 'Alex Klarfeld 911!'