Skip to content

Conversation

jap
Copy link

@jap jap commented Sep 15, 2025

This series of commits brings some typing improvements, but also adds the option to return the timecode that matched when verifying a TOTP, which is a feature in passlib.totp but that project appears to no longer be maintained.

  • Add option to return the timecode that matched when verifying TOTP.
  • typing: accept float for timestamp values
  • typing: add explicit isinstance asserts to tests
  • typing: don't construct TOTP instances with a secret that is bytes
  • tests: make the Timecop more pythonic
  • refactor: remove testing of stdlib code
  • lint: perform typing checks on test.py as well

@jap jap marked this pull request as ready for review September 15, 2025 12:11
jap added 7 commits September 17, 2025 12:51
This adds a boolean option `return_timecode` to TOTP.verify that
changes its return value on success to an integer containing the
timecode that was used to generate the matching OTP.

This is especially useful when `valid_window` is not 0, as then
several values might be valid at the same moment. If an implementation
compares just the bare OTP, replaying a recent value is possible.
By comparing timecodes, that can be prevented, as they are strictly
increasing.

The patch also fixes a minor typing issue, as the `for_time` argument
can also be an number - there even is a test that calls it like this.

Finally, the special case for `valid_window == 0` has been removed as
it is a micro-optimization that only leads to repeated code.
Tests were already passing -29.5 to `TOTP.at`; note that casting a
float to an int in Python just strips off the fractional part (like
`floor(3)`). Because TOTP intervals are integers, this means that this
rounding off operation does not change which interval the timestamp is
in so we can do this safely.
This allows mypy to infer that the called methods actually exist.

Note that two self.assertIsInstance got replaced by these; the tests
will still fail on type mismatch.
This accidentally worked but the typing police does not like it.
This removes a bunch of test calls against compare_digest which is
imported from the standard library, and not exposed to users of this
library.

Mypy also did not like this.
@jap jap force-pushed the typing-improvements branch from 8143db2 to acd7917 Compare September 17, 2025 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant