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.
- pyotp-2.11.1/.github/FUNDING.yml +3 -0
- pyotp-2.11.1/.github/workflows/actions.lock +64 -0
- pyotp-2.11.1/.github/workflows/ci.yml +31 -0
- pyotp-2.11.1/.github/workflows/release.yml +21 -0
- pyotp-2.11.1/.gitignore +42 -0
- pyotp-2.11.1/Changes.rst +203 -0
- pyotp-2.11.1/Makefile +31 -0
- {pyotp-2.9.0/src/pyotp.egg-info → pyotp-2.11.1}/PKG-INFO +47 -28
- {pyotp-2.9.0 → pyotp-2.11.1}/README.rst +23 -13
- pyotp-2.11.1/SECURITY.md +9 -0
- pyotp-2.11.1/common.mk +55 -0
- pyotp-2.11.1/docs/changelog.rst +3 -0
- pyotp-2.11.1/docs/conf.py +36 -0
- pyotp-2.11.1/docs/index.rst +27 -0
- pyotp-2.11.1/docs/toc.html +1 -0
- pyotp-2.11.1/pyproject.toml +66 -0
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/__init__.py +28 -22
- pyotp-2.11.1/src/pyotp/compat.py +3 -0
- pyotp-2.11.1/src/pyotp/contrib/__init__.py +1 -0
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/contrib/steam.py +7 -15
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/hotp.py +13 -9
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/otp.py +11 -5
- pyotp-2.11.1/src/pyotp/totp.py +183 -0
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/utils.py +18 -14
- {pyotp-2.9.0 → pyotp-2.11.1}/test.py +303 -16
- pyotp-2.9.0/PKG-INFO +0 -211
- pyotp-2.9.0/pyproject.toml +0 -9
- pyotp-2.9.0/setup.cfg +0 -4
- pyotp-2.9.0/setup.py +0 -45
- pyotp-2.9.0/src/pyotp/compat.py +0 -7
- pyotp-2.9.0/src/pyotp/contrib/__init__.py +0 -1
- pyotp-2.9.0/src/pyotp/totp.py +0 -119
- pyotp-2.9.0/src/pyotp.egg-info/SOURCES.txt +0 -21
- pyotp-2.9.0/src/pyotp.egg-info/dependency_links.txt +0 -1
- pyotp-2.9.0/src/pyotp.egg-info/not-zip-safe +0 -1
- pyotp-2.9.0/src/pyotp.egg-info/requires.txt +0 -6
- pyotp-2.9.0/src/pyotp.egg-info/top_level.txt +0 -1
- {pyotp-2.9.0 → pyotp-2.11.1}/LICENSE +0 -0
- {pyotp-2.9.0 → pyotp-2.11.1}/MANIFEST.in +0 -0
- {pyotp-2.9.0 → pyotp-2.11.1}/src/pyotp/py.typed +0 -0
|
@@ -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
|
pyotp-2.11.1/.gitignore
ADDED
|
@@ -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
|
pyotp-2.11.1/Changes.rst
ADDED
|
@@ -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.
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: PyOTP
|
|
3
|
+
Version: 2.11.1
|
|
4
4
|
Summary: Python One Time Password Library
|
|
5
|
-
|
|
6
|
-
|
|
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/
|
|
13
|
-
|
|
14
|
-
|
|
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.
|
|
32
|
+
Requires-Python: >=3.8
|
|
28
33
|
Provides-Extra: test
|
|
29
|
-
|
|
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
|
|
58
|
-
MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a
|
|
59
|
-
device, which strengthens your clients against client-side attacks. And by automating scoping
|
|
60
|
-
relying party IDs (application origin/domain names), U2F adds protection against phishing attacks.
|
|
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://
|
|
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
|
-
|
|
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
|
|
28
|
-
MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a
|
|
29
|
-
device, which strengthens your clients against client-side attacks. And by automating scoping
|
|
30
|
-
relying party IDs (application origin/domain names), U2F adds protection against phishing attacks.
|
|
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://
|
|
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
|
-
|
|
143
|
+
.. code:: python
|
|
134
144
|
|
|
135
145
|
import pyotp
|
|
136
146
|
totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
|
pyotp-2.11.1/SECURITY.md
ADDED
|
@@ -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.
|