Skip to content

Commit

Permalink
more fixups to redaction
Browse files Browse the repository at this point in the history
  • Loading branch information
jeking3 committed Sep 24, 2020
1 parent c3b36fa commit abfd513
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
21 changes: 12 additions & 9 deletions interposer/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,21 @@ def tearDownClass(cls) -> None:

super().tearDownClass()

def redact(self, secret: str, replacement: str = "*") -> str:
def redact(self, secret: str, identifier: str) -> str:
"""
Redact a secret in playback mode, and keep track of the secret in
recording mode. This allows tests to use secrets quite normally.
Callers just have to remember to run secrets through redact().
In recording mode, pass in the secret and a unique identifier that
will be present during playback that identifies the secret. The
content in the recording will be redacted using the identifier.
It is recommended you provide a unique replacment string (it does
not need to be the same length as the secret), for each secret
to disambiguate them in the same run, especially for secrets of the
same length.
In playback mode, pass in anything plus the same unique identifier
that was present during recording and the redaction will be returned
for you to use in place of the secret. Then your call will align
with the recording's call, even though you did not use the same
actual secret.
Each identifier for a secret must be unique.
"""
return self.tapedeck.redact(secret, replacement=replacement)
return self.tapedeck.redact(secret, identifier)


class TapeDeckCallHandler(CallHandler):
Expand Down
11 changes: 5 additions & 6 deletions tests/recorder_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,19 +316,18 @@ def test_secrets(self):
# the secrets get redacted; in playback mode this redacts it immediately
# so the playback matches the recording
assert not self.tapedeck._redactions
uut = cls(self.redact(self.token, replacement="TOKEN"))
uut = cls(self.redact(self.token, "TOKEN"))
assert self.tapedeck._redactions
assert uut.get_token() == self.redact(self.token, replacement="TOKEN")
assert self.redact(self.token) == self.token
assert uut.get_token() == self.redact(self.token, "TOKEN2")

self.tapedeck.close() # applies redaction to recording
self.tapedeck.mode = Mode.Playback
self.tapedeck.open()

assert not self.tapedeck._redactions
uut = cls(self.redact(self.token, replacement="TOKEN"))
foo = self.redact(self.token, replacement="TOKEN")
assert foo == "TOKENTOKENTOKENTOKENTOKENTOKENTOKENT"
uut = cls(self.redact("foo", "TOKEN"))
foo = self.redact("foo", "TOKEN")
assert foo == "TOKEN_______________________________"

# most importantly, the object initializer argument was redacted
assert uut.get_token() == foo
Expand Down

0 comments on commit abfd513

Please sign in to comment.