PyOTP 2.9.0__tar.gz → 2.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. pyotp-2.11.1/.github/FUNDING.yml +3 -0
  2. pyotp-2.11.1/.github/workflows/actions.lock +64 -0
  3. pyotp-2.11.1/.github/workflows/ci.yml +31 -0
  4. pyotp-2.11.1/.github/workflows/release.yml +21 -0
  5. pyotp-2.11.1/.gitignore +42 -0
  6. pyotp-2.11.1/Changes.rst +203 -0
  7. pyotp-2.11.1/Makefile +31 -0
  8. {pyotp-2.9.0/src/pyotp.egg-info → pyotp-2.11.1}/PKG-INFO +47 -28
  9. {pyotp-2.9.0 → pyotp-2.11.1}/README.rst +23 -13
  10. pyotp-2.11.1/SECURITY.md +9 -0
  11. pyotp-2.11.1/common.mk +55 -0
  12. pyotp-2.11.1/docs/changelog.rst +3 -0
  13. pyotp-2.11.1/docs/conf.py +36 -0
  14. pyotp-2.11.1/docs/index.rst +27 -0
  15. pyotp-2.11.1/docs/toc.html +1 -0
  16. pyotp-2.11.1/pyproject.toml +66 -0
  17. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/__init__.py +28 -22
  18. pyotp-2.11.1/src/pyotp/compat.py +3 -0
  19. pyotp-2.11.1/src/pyotp/contrib/__init__.py +1 -0
  20. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/contrib/steam.py +7 -15
  21. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/hotp.py +13 -9
  22. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/otp.py +11 -5
  23. pyotp-2.11.1/src/pyotp/totp.py +183 -0
  24. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/utils.py +18 -14
  25. {pyotp-2.9.0 → pyotp-2.11.1}/test.py +303 -16
  26. pyotp-2.9.0/PKG-INFO +0 -211
  27. pyotp-2.9.0/pyproject.toml +0 -9
  28. pyotp-2.9.0/setup.cfg +0 -4
  29. pyotp-2.9.0/setup.py +0 -45
  30. pyotp-2.9.0/src/pyotp/compat.py +0 -7
  31. pyotp-2.9.0/src/pyotp/contrib/__init__.py +0 -1
  32. pyotp-2.9.0/src/pyotp/totp.py +0 -119
  33. pyotp-2.9.0/src/pyotp.egg-info/SOURCES.txt +0 -21
  34. pyotp-2.9.0/src/pyotp.egg-info/dependency_links.txt +0 -1
  35. pyotp-2.9.0/src/pyotp.egg-info/not-zip-safe +0 -1
  36. pyotp-2.9.0/src/pyotp.egg-info/requires.txt +0 -6
  37. pyotp-2.9.0/src/pyotp.egg-info/top_level.txt +0 -1
  38. {pyotp-2.9.0 → pyotp-2.11.1}/LICENSE +0 -0
  39. {pyotp-2.9.0 → pyotp-2.11.1}/MANIFEST.in +0 -0
  40. {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/py.typed +0 -0
@@ -0,0 +1,3 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: kislyuk
@@ -0,0 +1,64 @@
1
+ # This file is machine-generated by `gh actions-lock`.
2
+ # Do not edit by hand; run `gh actions-lock` to update.
3
+ # Docs: https://gh.io/actions-lockfile
4
+ version: 'v0.0.3'
5
+ workflows:
6
+ '.github/workflows/ci.yml':
7
+ - 'actions/checkout@v7'
8
+ - 'actions/setup-python@v7'
9
+ - 'astral-sh/ruff-action@v4.1.0'
10
+ - 'codecov/codecov-action@v7'
11
+ '.github/workflows/release.yml':
12
+ - 'actions/checkout@v4'
13
+ - 'actions/setup-python@v5'
14
+ - 'pypa/gh-action-pypi-publish@release/v1'
15
+ dependencies:
16
+ 'actions/checkout@v4':
17
+ ref: 'v4'
18
+ commit: 'sha1-11d5960a326750d5838078e36cf38b85af677262'
19
+ owner_id: 44036562
20
+ repo_id: 197814629
21
+ 'actions/checkout@v7':
22
+ ref: 'v7'
23
+ commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1'
24
+ owner_id: 44036562
25
+ repo_id: 197814629
26
+ 'actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd':
27
+ ref: 'v8.0.0'
28
+ commit: 'sha1-ed597411d8f924073f98dfc5c65a23a2325f34cd'
29
+ owner_id: 44036562
30
+ repo_id: 205262760
31
+ 'actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405':
32
+ ref: 'v6.2.0'
33
+ commit: 'sha1-a309ff8b426b58ec0e2a45f0f869d46889d02405'
34
+ owner_id: 44036562
35
+ repo_id: 192625525
36
+ 'actions/setup-python@v5':
37
+ ref: 'v5'
38
+ commit: 'sha1-a26af69be951a213d495a4c3e4e4022e16d87065'
39
+ owner_id: 44036562
40
+ repo_id: 192625525
41
+ 'actions/setup-python@v7':
42
+ ref: 'v7'
43
+ commit: 'sha1-6d4fd22b20465ccc0f7354476588e8df7c9ca0e0'
44
+ owner_id: 44036562
45
+ repo_id: 192625525
46
+ 'astral-sh/ruff-action@v4.1.0':
47
+ ref: 'v4.1.0'
48
+ commit: 'sha1-278981a28ce3188b1e39527901f38254bf3aac89'
49
+ owner_id: 115962839
50
+ repo_id: 865075538
51
+ 'codecov/codecov-action@v7':
52
+ ref: 'v7'
53
+ commit: 'sha1-303a32d7a59b442fa8d48b6a1cc6825c09c847a5'
54
+ owner_id: 8226205
55
+ repo_id: 200299178
56
+ uses:
57
+ - 'actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd'
58
+ 'pypa/gh-action-pypi-publish@release/v1':
59
+ ref: 'release/v1'
60
+ commit: 'sha1-7245906fb61fa33a13554f9d5fb856fe61758086'
61
+ owner_id: 647025
62
+ repo_id: 178055147
63
+ uses:
64
+ - 'actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405'
@@ -0,0 +1,31 @@
1
+ name: Python package
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ${{ matrix.os }}
8
+ env:
9
+ PIP_DISABLE_PIP_VERSION_CHECK: 1
10
+ strategy:
11
+ matrix:
12
+ os: [ubuntu-22.04, ubuntu-latest, macos-latest]
13
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v7
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - run: make install
21
+ - run: make lint
22
+ - run: make test
23
+ - uses: codecov/codecov-action@v7
24
+ ruff:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v7
28
+ - uses: astral-sh/ruff-action@v4.1.0
29
+ - uses: astral-sh/ruff-action@v4.1.0
30
+ with:
31
+ args: "format --check"
@@ -0,0 +1,21 @@
1
+ name: Publish release to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v[0-9]+.[0-9]+.[0-9]+'
7
+
8
+ jobs:
9
+ pypi-publish:
10
+ name: Build and upload release to PyPI
11
+ runs-on: ubuntu-latest
12
+ environment: release
13
+ permissions:
14
+ id-token: write
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ - run: pip install build
19
+ - run: python -m build
20
+ - name: Publish package distributions to PyPI
21
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,42 @@
1
+ # Reminder:
2
+ # - A leading slash means the pattern is anchored at the root.
3
+ # - No leading slash means the pattern matches at any depth.
4
+
5
+ # Python files
6
+ *.pyc
7
+ __pycache__/
8
+ .tox/
9
+ *.egg-info/
10
+ /build/
11
+ /dist/
12
+ /.eggs/
13
+
14
+ # Sphinx documentation
15
+ /docs/_build/
16
+
17
+ # IDE project files
18
+ /.pydevproject
19
+
20
+ # vim python-mode plugin
21
+ /.ropeproject
22
+
23
+ # IntelliJ IDEA / PyCharm project files
24
+ /.idea
25
+ /*.iml
26
+
27
+ # JS/node/npm/web dev files
28
+ node_modules
29
+ npm-debug.log
30
+
31
+ # OS X metadata files
32
+ .DS_Store
33
+
34
+ # Python coverage
35
+ .coverage
36
+ htmlcov
37
+
38
+ # Virtual environments
39
+ venv
40
+
41
+ # Type checking
42
+ .mypy_cache
@@ -0,0 +1,203 @@
1
+ Changes for v2.11.1 (2026-11-14)
2
+ ================================
3
+
4
+ - Fix PyPI README markup and validate distributions before release
5
+ (#200)
6
+
7
+ Changes for v2.11.0 (2026-11-14)
8
+ ================================
9
+
10
+ - Fix DST rollbacks and normalize TOTP timestamp inputs (#197)
11
+
12
+ - Respect initial_count=0 in HOTP.provisioning_uri() (#190)
13
+
14
+ - Implement verify_and_get_timecode, a method for TOTP that verifies
15
+ and returns the matching timecode (#191)
16
+
17
+ Changes for v2.10.0 (2026-06-13)
18
+ ================================
19
+
20
+ - Fix parse_uri mis-parsing of encoded colon in issuer/account name
21
+ (#187)
22
+
23
+ - Simplified and improved generate_otp() performance in Steam class
24
+ (#179)
25
+
26
+ - Check digest function to prevent error on OTP Generation (#170)
27
+
28
+ - Ignore non-standard otpauth parameters
29
+
30
+ - use strings as immutable default arguments (#162)
31
+
32
+ Changes for v2.9.0 (2023-07-27)
33
+ ===============================
34
+
35
+ - Add ``parse_uri()`` support for Steam TOTP (#153)
36
+
37
+ - Test and documentation improvements
38
+
39
+ Changes for v2.8.0 (2022-12-13)
40
+ ===============================
41
+
42
+ - Modify OTP generation to run in constant time (#148)
43
+
44
+ - Documentation improvements
45
+
46
+ - Drop Python 3.6 support; introduce Python 3.11 support
47
+
48
+ Changes for v2.7.0 (2022-09-11)
49
+ ===============================
50
+
51
+ - Support Steam TOTP (#142)
52
+
53
+ - Build, test, and documentation updates
54
+
55
+ Changes for v2.6.0 (2021-02-04)
56
+ ===============================
57
+
58
+ - Raise default and minimum base32 secret length to 32, and hex secret
59
+ length to 40 (160 bits as recommended by the RFC) (#115).
60
+
61
+ - Fix issue where provisioning_uri would return invalid results after
62
+ calling verify() (#115).
63
+
64
+ Changes for v2.5.1 (2021-01-29)
65
+ ===============================
66
+
67
+ - parse_uri accepts and ignores optional image parameter (#114)
68
+
69
+ Changes for v2.5.0 (2021-01-29)
70
+ ===============================
71
+
72
+ - Add optional image parameter to provisioning_uri (#113)
73
+
74
+ - Support for 7-digit codes in ‘parse_uri’ (#111)
75
+
76
+ - Raise default and minimum base32 secret length to 26
77
+
78
+ Changes for v2.4.1 (2020-10-16)
79
+ ===============================
80
+
81
+ - parse_uri: Fix handling of period, counter (#108)
82
+
83
+ - Add support for timezone aware datetime as argument to
84
+ ``TOTP.timecode()`` (#107)
85
+
86
+ Changes for v2.4.0 (2020-07-29)
87
+ ===============================
88
+
89
+ - Fix data type for at(for_time) (#85)
90
+
91
+ - Add support for parsing provisioning URIs (#84)
92
+
93
+ - Raise error when trying to generate secret that is too short (The
94
+ secret must be at least 128 bits)
95
+
96
+ - Add random_hex function (#82)
97
+
98
+ Changes for v2.3.0 (2019-07-26)
99
+ ===============================
100
+
101
+ - Fix comparison behavior on Python 2.7
102
+
103
+ Changes for v2.2.8 (2019-07-26)
104
+ ===============================
105
+
106
+ - Fix comparison of unicode chars (#78)
107
+
108
+ - Minor documentation and test fixes
109
+
110
+ Changes for v2.2.7 (2018-11-05)
111
+ ===============================
112
+
113
+ - Have random_base32() use ‘secrets’ as rand source (#66)
114
+
115
+ - Documentation: Add security considerations, minimal security
116
+ checklist, other improvements
117
+
118
+ - Update setup.py to reference correct license
119
+
120
+ Changes for v2.2.6 (2017-06-10)
121
+ ===============================
122
+
123
+ - Fix tests wrt double-quoting in provisioning URIs
124
+
125
+ Changes for v2.2.5 (2017-06-03)
126
+ ===============================
127
+
128
+ - Quote issuer QS parameter in provisioning\_uri. Fixes #47.
129
+
130
+ - Raise an exception if a negative integer is passed to at() (#41).
131
+
132
+ - Documentation and release infrastructure improvements.
133
+
134
+ Changes for v2.2.4 (2017-01-04)
135
+ ===============================
136
+
137
+ - Restore Python 2.6 compatibility (however, Python 2.6 is not
138
+ supported)
139
+
140
+ - Documentation and test improvements
141
+
142
+ - Fix release infra script, part 2
143
+
144
+ Changes for v2.2.3 (2017-01-04)
145
+ ===============================
146
+
147
+ - Restore Python 2.6 compatibility (however, Python 2.6 is not
148
+ supported)
149
+
150
+ - Documentation and test improvements
151
+
152
+ - Fix release infra script
153
+
154
+ Changes for v2.2.2 (2017-01-04)
155
+ ===============================
156
+
157
+ - Restore Python 2.6 compatibility (however, Python 2.6 is not
158
+ supported)
159
+
160
+ - Documentation and test improvements
161
+
162
+ Changes for v2.2.1 (2016-08-30)
163
+ ===============================
164
+
165
+ - Avoid using python-future; it has subdependencies that limit
166
+ compatibility (#34)
167
+ - Make test suite pass on 32-bit platforms (#30)
168
+ - Timing attack resistance fix: don't reveal string length to attacker.
169
+ Thanks to Eeo Jun (#28).
170
+ - Support algorithm, digits, period parameters in provisioning\_uri.
171
+ Thanks to Dionisio E Alonso (#33).
172
+ - Minor style and packaging infrastructure fixes.
173
+
174
+ Changes for v2.2.0 (2016-08-30)
175
+ ===============================
176
+
177
+ - See v2.2.1
178
+
179
+ Version 2.1.0 (2016-05-02)
180
+ --------------------------
181
+ - Add extended range support to TOTP.verify. Thanks to Zeev Rotshtein (PR #19).
182
+ - Handle missing padding of encoded secret. Thanks to Kun Yan (#20).
183
+ - Miscellaneous fixes.
184
+
185
+ Version 2.0.1 (2015-09-28)
186
+ --------------------------
187
+ - Fix packaging issue in v2.0.0 that prevented installation with easy_install.
188
+
189
+ Version 2.0.0 (2015-08-22)
190
+ --------------------------
191
+ - The ``pyotp.HOTP.at()``, ``pyotp.TOTP.at()``, and
192
+ ``pyotp.TOTP.now()`` methods now return strings instead of
193
+ integers. Thanks to Rohan Dhaimade (PR #16).
194
+
195
+ Version 1.4.2 (2015-07-21)
196
+ --------------------------
197
+ - Begin tracking changes in change log.
198
+ - Update documentation.
199
+ - Introduce Travis CI integration.
200
+
201
+ Version 1.3.1 (2012-02-29)
202
+ --------------------------
203
+ - Initial release.
pyotp-2.11.1/Makefile ADDED
@@ -0,0 +1,31 @@
1
+ SHELL=/bin/bash
2
+
3
+ test_deps:
4
+ python -m pip install .[test]
5
+
6
+ lint:
7
+ ruff check src
8
+ mypy --install-types --non-interactive --check-untyped-defs src
9
+
10
+ test:
11
+ coverage run --branch --include 'src/*' -m unittest discover -s test -v
12
+
13
+ init_docs:
14
+ cd docs; sphinx-quickstart
15
+
16
+ docs:
17
+ python -m pip install furo sphinx-copybutton sphinxext-opengraph
18
+ sphinx-build docs docs/html
19
+
20
+ install: clean
21
+ python -m pip install build
22
+ python -m build
23
+ python -m pip install --upgrade $$(echo dist/*.whl)[test]
24
+
25
+ clean:
26
+ -rm -rf build dist
27
+ -rm -rf *.egg-info
28
+
29
+ .PHONY: test_deps lint test docs install clean
30
+
31
+ include common.mk
@@ -1,32 +1,41 @@
1
- Metadata-Version: 2.1
2
- Name: pyotp
3
- Version: 2.9.0
1
+ Metadata-Version: 2.5
2
+ Name: PyOTP
3
+ Version: 2.11.1
4
4
  Summary: Python One Time Password Library
5
- Home-page: https://github.com/pyotp/pyotp
6
- Author: PyOTP contributors
7
- Author-email: kislyuk@gmail.com
8
- License: MIT License
9
- Project-URL: Documentation, https://pyauth.github.io/pyotp
5
+ Project-URL: Homepage, https://github.com/pyauth/pyotp
6
+ Project-URL: Documentation, https://github.com/pyauth/pyotp
10
7
  Project-URL: Source Code, https://github.com/pyauth/pyotp
11
8
  Project-URL: Issue Tracker, https://github.com/pyauth/pyotp/issues
12
- Project-URL: Change Log, https://github.com/pyauth/pyotp/blob/master/Changes.rst
13
- Platform: MacOS X
14
- Platform: Posix
9
+ Project-URL: Change Log, https://github.com/pyauth/pyotp/blob/main/Changes.rst
10
+ Author: Andrey Kislyuk
11
+ Author-email: kislyuk@gmail.com
12
+ Maintainer: Andrey Kislyuk
13
+ Maintainer-email: kislyuk@gmail.com
14
+ License-Expression: MIT
15
+ License-File: LICENSE
16
+ Classifier: Development Status :: 5 - Production/Stable
15
17
  Classifier: Intended Audience :: Developers
16
- Classifier: License :: OSI Approved :: MIT License
17
18
  Classifier: Operating System :: MacOS :: MacOS X
18
19
  Classifier: Operating System :: POSIX
19
20
  Classifier: Programming Language :: Python
20
21
  Classifier: Programming Language :: Python :: 3
21
- Classifier: Programming Language :: Python :: 3.7
22
22
  Classifier: Programming Language :: Python :: 3.8
23
23
  Classifier: Programming Language :: Python :: 3.9
24
24
  Classifier: Programming Language :: Python :: 3.10
25
25
  Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
28
+ Classifier: Programming Language :: Python :: Implementation :: CPython
29
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
30
+ Classifier: Topic :: Software Development
26
31
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
- Requires-Python: >=3.7
32
+ Requires-Python: >=3.8
28
33
  Provides-Extra: test
29
- License-File: LICENSE
34
+ Requires-Dist: coverage; extra == 'test'
35
+ Requires-Dist: mypy; extra == 'test'
36
+ Requires-Dist: ruff; extra == 'test'
37
+ Requires-Dist: wheel; extra == 'test'
38
+ Description-Content-Type: text/x-rst
30
39
 
31
40
  PyOTP - The Python One-Time Password Library
32
41
  ============================================
@@ -54,11 +63,11 @@ minimum, application implementers should follow this checklist:
54
63
  - Throttle (rate limit) brute-force attacks against your application's login functionality (see RFC 4226, section 7.3)
55
64
  - When implementing a "greenfield" application, consider supporting
56
65
  `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
57
- addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
58
- MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
59
- device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
60
- relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation
61
- of FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
66
+ addition to or instead of HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which
67
+ strengthens your MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a
68
+ dedicated single-purpose device, which strengthens your clients against client-side attacks. And by automating scoping
69
+ of credentials to relying party IDs (application origin/domain names), U2F adds protection against phishing attacks.
70
+ One implementation of FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
62
71
 
63
72
  We also recommend that implementers read the
64
73
  `OWASP Authentication Cheat Sheet
@@ -87,7 +96,7 @@ Usage
87
96
 
88
97
  Time-based OTPs
89
98
  ~~~~~~~~~~~~~~~
90
- ::
99
+ .. code:: python
91
100
 
92
101
  import pyotp
93
102
  import time
@@ -102,7 +111,7 @@ Time-based OTPs
102
111
 
103
112
  Counter-based OTPs
104
113
  ~~~~~~~~~~~~~~~~~~
105
- ::
114
+ .. code:: python
106
115
 
107
116
  import pyotp
108
117
 
@@ -118,11 +127,15 @@ Counter-based OTPs
118
127
  Generating a Secret Key
119
128
  ~~~~~~~~~~~~~~~~~~~~~~~
120
129
  A helper function is provided to generate a 32-character base32 secret, compatible with Google Authenticator and other
121
- OTP apps::
130
+ OTP apps:
131
+
132
+ .. code:: python
122
133
 
123
134
  pyotp.random_base32()
124
135
 
125
- Some applications want the secret key to be formatted as a hex-encoded string::
136
+ Some applications want the secret key to be formatted as a hex-encoded string:
137
+
138
+ .. code:: python
126
139
 
127
140
  pyotp.random_hex() # returns a 40-character hex-encoded secret
128
141
 
@@ -130,7 +143,9 @@ Google Authenticator Compatible
130
143
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131
144
 
132
145
  PyOTP works with the Google Authenticator iPhone and Android app, as well as other OTP apps like Authy. PyOTP includes
133
- the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps::
146
+ the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps:
147
+
148
+ .. code:: python
134
149
 
135
150
  pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name='alice@google.com', issuer_name='Secure App')
136
151
 
@@ -143,7 +158,9 @@ the ability to generate provisioning URIs for use with the QR Code scanner built
143
158
  This URL can then be rendered as a QR Code (for example, using https://github.com/soldair/node-qrcode) which can then be
144
159
  scanned and added to the users list of OTP credentials.
145
160
 
146
- Parsing these URLs is also supported::
161
+ Parsing these URLs is also supported:
162
+
163
+ .. code:: python
147
164
 
148
165
  pyotp.parse_uri('otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App')
149
166
 
@@ -158,9 +175,11 @@ Working example
158
175
 
159
176
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
160
177
 
161
- .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
178
+ .. image:: https://quickchart.io/qr?size=250&text=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
179
+
180
+ Now run the following and compare the output:
162
181
 
163
- Now run the following and compare the output::
182
+ .. code:: python
164
183
 
165
184
  import pyotp
166
185
  totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
@@ -24,11 +24,11 @@ minimum, application implementers should follow this checklist:
24
24
  - Throttle (rate limit) brute-force attacks against your application's login functionality (see RFC 4226, section 7.3)
25
25
  - When implementing a "greenfield" application, consider supporting
26
26
  `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
27
- addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
28
- MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
29
- device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
30
- relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation
31
- of FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
27
+ addition to or instead of HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which
28
+ strengthens your MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a
29
+ dedicated single-purpose device, which strengthens your clients against client-side attacks. And by automating scoping
30
+ of credentials to relying party IDs (application origin/domain names), U2F adds protection against phishing attacks.
31
+ One implementation of FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
32
32
 
33
33
  We also recommend that implementers read the
34
34
  `OWASP Authentication Cheat Sheet
@@ -57,7 +57,7 @@ Usage
57
57
 
58
58
  Time-based OTPs
59
59
  ~~~~~~~~~~~~~~~
60
- ::
60
+ .. code:: python
61
61
 
62
62
  import pyotp
63
63
  import time
@@ -72,7 +72,7 @@ Time-based OTPs
72
72
 
73
73
  Counter-based OTPs
74
74
  ~~~~~~~~~~~~~~~~~~
75
- ::
75
+ .. code:: python
76
76
 
77
77
  import pyotp
78
78
 
@@ -88,11 +88,15 @@ Counter-based OTPs
88
88
  Generating a Secret Key
89
89
  ~~~~~~~~~~~~~~~~~~~~~~~
90
90
  A helper function is provided to generate a 32-character base32 secret, compatible with Google Authenticator and other
91
- OTP apps::
91
+ OTP apps:
92
+
93
+ .. code:: python
92
94
 
93
95
  pyotp.random_base32()
94
96
 
95
- Some applications want the secret key to be formatted as a hex-encoded string::
97
+ Some applications want the secret key to be formatted as a hex-encoded string:
98
+
99
+ .. code:: python
96
100
 
97
101
  pyotp.random_hex() # returns a 40-character hex-encoded secret
98
102
 
@@ -100,7 +104,9 @@ Google Authenticator Compatible
100
104
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
105
 
102
106
  PyOTP works with the Google Authenticator iPhone and Android app, as well as other OTP apps like Authy. PyOTP includes
103
- the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps::
107
+ the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps:
108
+
109
+ .. code:: python
104
110
 
105
111
  pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name='alice@google.com', issuer_name='Secure App')
106
112
 
@@ -113,7 +119,9 @@ the ability to generate provisioning URIs for use with the QR Code scanner built
113
119
  This URL can then be rendered as a QR Code (for example, using https://github.com/soldair/node-qrcode) which can then be
114
120
  scanned and added to the users list of OTP credentials.
115
121
 
116
- Parsing these URLs is also supported::
122
+ Parsing these URLs is also supported:
123
+
124
+ .. code:: python
117
125
 
118
126
  pyotp.parse_uri('otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App')
119
127
 
@@ -128,9 +136,11 @@ Working example
128
136
 
129
137
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
130
138
 
131
- .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
139
+ .. image:: https://quickchart.io/qr?size=250&text=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
140
+
141
+ Now run the following and compare the output:
132
142
 
133
- Now run the following and compare the output::
143
+ .. code:: python
134
144
 
135
145
  import pyotp
136
146
  totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
@@ -0,0 +1,9 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ If you believe you have found a security vulnerability in this project, please report it to us by submitting a security advisory at https://github.com/pyauth/pyotp/security/advisories. You can expect an initial response within 14 days.
6
+
7
+ ## Supported Versions
8
+
9
+ In general, the maintainers of this project provide security updates only for the most recent published release. If you need support for prior versions, please open an issue and describe your situation. Requests for updates to prior releases will be considered on a case-by-case basis, and will generally be accommodated only for the latest releases in prior major version release series.