forge-mvc-mfa 1.0.0b8__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.
- forge_mvc_mfa-1.0.0b8/PKG-INFO +106 -0
- forge_mvc_mfa-1.0.0b8/README.md +85 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/__init__.py +144 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/mfa.py +959 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/model.py +59 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/recovery.py +275 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/secret_crypto.py +76 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa/totp_replay.py +81 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa.egg-info/PKG-INFO +106 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa.egg-info/SOURCES.txt +13 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa.egg-info/dependency_links.txt +1 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa.egg-info/requires.txt +3 -0
- forge_mvc_mfa-1.0.0b8/forge_mvc_mfa.egg-info/top_level.txt +1 -0
- forge_mvc_mfa-1.0.0b8/pyproject.toml +36 -0
- forge_mvc_mfa-1.0.0b8/setup.cfg +4 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: forge-mvc-mfa
|
|
3
|
+
Version: 1.0.0b8
|
|
4
|
+
Summary: Brique MFA pour Forge — TOTP et codes de récupération.
|
|
5
|
+
Author: Roger Cauchon
|
|
6
|
+
License-Expression: LicenseRef-Forge-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/caucrogeGit/Forge
|
|
8
|
+
Project-URL: Repository, https://github.com/caucrogeGit/Forge
|
|
9
|
+
Project-URL: Documentation, https://caucrogegit.github.io/Forge/
|
|
10
|
+
Keywords: python,mvc,forge,mfa,totp
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: forge-mvc==1.0.0b8
|
|
19
|
+
Requires-Dist: pyotp<3,>=2.9
|
|
20
|
+
Requires-Dist: cryptography<46,>=42
|
|
21
|
+
|
|
22
|
+
# forge-mvc-mfa
|
|
23
|
+
|
|
24
|
+
Brique MFA (TOTP + codes de récupération) pour le framework Forge.
|
|
25
|
+
|
|
26
|
+
## Statut : Alpha — préparé pour publication future (MFA-PYPI-READY-001)
|
|
27
|
+
|
|
28
|
+
`forge-mvc-mfa` est marqué `Development Status :: 3 - Alpha`.
|
|
29
|
+
|
|
30
|
+
Depuis `SEC-MFA-SECRET-ENCRYPTION-001`, **le secret TOTP est chiffré au repos**
|
|
31
|
+
via Fernet (`cryptography`). La clé est lue depuis `FORGE_MFA_SECRET_KEY` —
|
|
32
|
+
obligatoire au démarrage.
|
|
33
|
+
|
|
34
|
+
Le module **n'est pas publié sur PyPI dans la vague `1.0.0b7`**.
|
|
35
|
+
Non inclus dans `forge-mvc[all]`. Publication prévue lors d'une release dédiée
|
|
36
|
+
après ticket `MFA-PYPI-READY-001`.
|
|
37
|
+
|
|
38
|
+
**Mode d'installation (Forge 3.0.x)** : `forge-mvc-mfa` n'est pas encore publié
|
|
39
|
+
sur PyPI. Installation depuis les sources (mode dev) :
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/caucrogeGit/Forge.git
|
|
43
|
+
cd Forge
|
|
44
|
+
pip install -e .
|
|
45
|
+
pip install -r requirements-dev.txt
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Configuration requise
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Générer une clé Fernet (à stocker dans .env ou un gestionnaire de secrets)
|
|
52
|
+
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Ajouter dans `.env` :
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
FORGE_MFA_SECRET_KEY=<clé générée ci-dessus>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Installation (mode source)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Depuis le dépôt Forge (mode développement)
|
|
65
|
+
pip install -r requirements-dev.txt # installe forge-mvc-mfa depuis packages/
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`forge-mvc-mfa` dépend de `pyotp>=2.9`.
|
|
69
|
+
|
|
70
|
+
## Utilisation
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from forge_mvc_mfa import (
|
|
74
|
+
AuthMfaFactor,
|
|
75
|
+
create_totp_factor,
|
|
76
|
+
confirm_totp_factor,
|
|
77
|
+
verify_mfa_challenge,
|
|
78
|
+
is_mfa_enabled,
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
L'API complète est exposée directement depuis `forge_mvc_mfa`.
|
|
83
|
+
Les fonctions privées (`_persist_session_changes`, `_session_user_matches`)
|
|
84
|
+
doivent être importées depuis `forge_mvc_mfa.mfa`.
|
|
85
|
+
|
|
86
|
+
## SQL
|
|
87
|
+
|
|
88
|
+
Les tables nécessaires se trouvent dans `sql/` :
|
|
89
|
+
|
|
90
|
+
- `sql/auth_mfa_factors.sql` — facteurs TOTP
|
|
91
|
+
- `sql/auth_mfa_recovery_codes.sql` — codes de récupération
|
|
92
|
+
|
|
93
|
+
Appliquer via `db:apply` ou directement sur la base.
|
|
94
|
+
|
|
95
|
+
## Compatibilité
|
|
96
|
+
|
|
97
|
+
Disponible séparément depuis Forge 2.4.0 (ADR-004, MFA-EXTRACT-001).
|
|
98
|
+
Les anciens chemins `core.auth.mfa`, `core.auth.recovery` et
|
|
99
|
+
`core.auth.totp_replay` ont été retirés en Forge 3.0.
|
|
100
|
+
|
|
101
|
+
## Limites connues
|
|
102
|
+
|
|
103
|
+
- Le store anti-replay et le rate-limit sont in-memory process-local.
|
|
104
|
+
En multi-worker, utiliser des sticky sessions.
|
|
105
|
+
- La politique de rotation et la procédure de sauvegarde/restauration de la
|
|
106
|
+
clé Fernet ne sont pas encore formalisées (exigences Beta restantes).
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# forge-mvc-mfa
|
|
2
|
+
|
|
3
|
+
Brique MFA (TOTP + codes de récupération) pour le framework Forge.
|
|
4
|
+
|
|
5
|
+
## Statut : Alpha — préparé pour publication future (MFA-PYPI-READY-001)
|
|
6
|
+
|
|
7
|
+
`forge-mvc-mfa` est marqué `Development Status :: 3 - Alpha`.
|
|
8
|
+
|
|
9
|
+
Depuis `SEC-MFA-SECRET-ENCRYPTION-001`, **le secret TOTP est chiffré au repos**
|
|
10
|
+
via Fernet (`cryptography`). La clé est lue depuis `FORGE_MFA_SECRET_KEY` —
|
|
11
|
+
obligatoire au démarrage.
|
|
12
|
+
|
|
13
|
+
Le module **n'est pas publié sur PyPI dans la vague `1.0.0b7`**.
|
|
14
|
+
Non inclus dans `forge-mvc[all]`. Publication prévue lors d'une release dédiée
|
|
15
|
+
après ticket `MFA-PYPI-READY-001`.
|
|
16
|
+
|
|
17
|
+
**Mode d'installation (Forge 3.0.x)** : `forge-mvc-mfa` n'est pas encore publié
|
|
18
|
+
sur PyPI. Installation depuis les sources (mode dev) :
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/caucrogeGit/Forge.git
|
|
22
|
+
cd Forge
|
|
23
|
+
pip install -e .
|
|
24
|
+
pip install -r requirements-dev.txt
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Configuration requise
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Générer une clé Fernet (à stocker dans .env ou un gestionnaire de secrets)
|
|
31
|
+
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Ajouter dans `.env` :
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
FORGE_MFA_SECRET_KEY=<clé générée ci-dessus>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Installation (mode source)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Depuis le dépôt Forge (mode développement)
|
|
44
|
+
pip install -r requirements-dev.txt # installe forge-mvc-mfa depuis packages/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`forge-mvc-mfa` dépend de `pyotp>=2.9`.
|
|
48
|
+
|
|
49
|
+
## Utilisation
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from forge_mvc_mfa import (
|
|
53
|
+
AuthMfaFactor,
|
|
54
|
+
create_totp_factor,
|
|
55
|
+
confirm_totp_factor,
|
|
56
|
+
verify_mfa_challenge,
|
|
57
|
+
is_mfa_enabled,
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
L'API complète est exposée directement depuis `forge_mvc_mfa`.
|
|
62
|
+
Les fonctions privées (`_persist_session_changes`, `_session_user_matches`)
|
|
63
|
+
doivent être importées depuis `forge_mvc_mfa.mfa`.
|
|
64
|
+
|
|
65
|
+
## SQL
|
|
66
|
+
|
|
67
|
+
Les tables nécessaires se trouvent dans `sql/` :
|
|
68
|
+
|
|
69
|
+
- `sql/auth_mfa_factors.sql` — facteurs TOTP
|
|
70
|
+
- `sql/auth_mfa_recovery_codes.sql` — codes de récupération
|
|
71
|
+
|
|
72
|
+
Appliquer via `db:apply` ou directement sur la base.
|
|
73
|
+
|
|
74
|
+
## Compatibilité
|
|
75
|
+
|
|
76
|
+
Disponible séparément depuis Forge 2.4.0 (ADR-004, MFA-EXTRACT-001).
|
|
77
|
+
Les anciens chemins `core.auth.mfa`, `core.auth.recovery` et
|
|
78
|
+
`core.auth.totp_replay` ont été retirés en Forge 3.0.
|
|
79
|
+
|
|
80
|
+
## Limites connues
|
|
81
|
+
|
|
82
|
+
- Le store anti-replay et le rate-limit sont in-memory process-local.
|
|
83
|
+
En multi-worker, utiliser des sticky sessions.
|
|
84
|
+
- La politique de rotation et la procédure de sauvegarde/restauration de la
|
|
85
|
+
clé Fernet ne sont pas encore formalisées (exigences Beta restantes).
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""forge-mvc-mfa — Module MFA pour Forge : TOTP, codes de recuperation, anti-replay, rate-limit.
|
|
2
|
+
|
|
3
|
+
Module officiel Forge distribue separement depuis Forge 2.4.0.
|
|
4
|
+
Voir packages/forge-mvc-mfa/README.md pour la documentation.
|
|
5
|
+
"""
|
|
6
|
+
from forge_mvc_mfa.secret_crypto import (
|
|
7
|
+
MfaSecretInvalidKey,
|
|
8
|
+
MfaSecretKeyMissing,
|
|
9
|
+
MfaSecretNotEncrypted,
|
|
10
|
+
decrypt_totp_secret,
|
|
11
|
+
encrypt_totp_secret,
|
|
12
|
+
)
|
|
13
|
+
from forge_mvc_mfa.mfa import (
|
|
14
|
+
MFA_CHALLENGE_STARTED_AT_KEY,
|
|
15
|
+
MFA_CHALLENGE_USER_ID_KEY,
|
|
16
|
+
MFA_CHALLENGE_MAX_ATTEMPTS,
|
|
17
|
+
MFA_CHALLENGE_WINDOW_SECONDS,
|
|
18
|
+
MFA_FACTOR_RECOVERY,
|
|
19
|
+
MFA_FACTOR_TOTP,
|
|
20
|
+
MFA_REVALIDATION_AT_KEY,
|
|
21
|
+
MFA_REVALIDATION_USER_ID_KEY,
|
|
22
|
+
MFA_REVALIDATION_MAX_ATTEMPTS,
|
|
23
|
+
MFA_REVALIDATION_WINDOW_SECONDS,
|
|
24
|
+
MFA_STATUS_ACTIVE,
|
|
25
|
+
MFA_STATUS_DISABLED,
|
|
26
|
+
MFA_STATUS_PENDING,
|
|
27
|
+
AuthMfaFactor,
|
|
28
|
+
MfaChallengeResult,
|
|
29
|
+
MfaRevalidationResult,
|
|
30
|
+
TotpSetup,
|
|
31
|
+
clear_mfa_challenge,
|
|
32
|
+
clear_mfa_revalidation,
|
|
33
|
+
confirm_totp_factor,
|
|
34
|
+
create_totp_factor,
|
|
35
|
+
generate_totp_secret,
|
|
36
|
+
get_mfa_challenge_user_id,
|
|
37
|
+
get_mfa_revalidated_user_id,
|
|
38
|
+
has_pending_mfa_challenge,
|
|
39
|
+
has_recent_mfa_revalidation,
|
|
40
|
+
is_mfa_enabled,
|
|
41
|
+
is_mfa_factor_active,
|
|
42
|
+
is_valid_mfa_factor,
|
|
43
|
+
mark_mfa_revalidated,
|
|
44
|
+
normalize_mfa_factor,
|
|
45
|
+
require_recent_mfa,
|
|
46
|
+
start_mfa_challenge,
|
|
47
|
+
totp_provisioning_uri,
|
|
48
|
+
validate_mfa_factor_contract,
|
|
49
|
+
verify_mfa_challenge,
|
|
50
|
+
verify_mfa_revalidation,
|
|
51
|
+
verify_totp_code,
|
|
52
|
+
)
|
|
53
|
+
from forge_mvc_mfa.recovery import (
|
|
54
|
+
AuthMfaRecoveryCode,
|
|
55
|
+
RecoveryCodesSetup,
|
|
56
|
+
consume_recovery_code,
|
|
57
|
+
create_recovery_codes,
|
|
58
|
+
generate_recovery_code,
|
|
59
|
+
hash_recovery_code,
|
|
60
|
+
is_valid_recovery_code_record,
|
|
61
|
+
normalize_recovery_code,
|
|
62
|
+
normalize_recovery_code_record,
|
|
63
|
+
validate_recovery_code_contract,
|
|
64
|
+
verify_recovery_code,
|
|
65
|
+
)
|
|
66
|
+
from forge_mvc_mfa.totp_replay import (
|
|
67
|
+
is_replay,
|
|
68
|
+
purge_all as purge_all_totp_replay,
|
|
69
|
+
purge_old,
|
|
70
|
+
record_used,
|
|
71
|
+
step_for_time,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
__version__ = "1.0.0b8"
|
|
75
|
+
|
|
76
|
+
__all__ = [
|
|
77
|
+
# mfa — facteurs et types
|
|
78
|
+
"AuthMfaFactor",
|
|
79
|
+
"MfaChallengeResult",
|
|
80
|
+
"MfaRevalidationResult",
|
|
81
|
+
"TotpSetup",
|
|
82
|
+
"MFA_FACTOR_TOTP",
|
|
83
|
+
"MFA_FACTOR_RECOVERY",
|
|
84
|
+
"MFA_STATUS_PENDING",
|
|
85
|
+
"MFA_STATUS_ACTIVE",
|
|
86
|
+
"MFA_STATUS_DISABLED",
|
|
87
|
+
# mfa — clés de session
|
|
88
|
+
"MFA_CHALLENGE_USER_ID_KEY",
|
|
89
|
+
"MFA_CHALLENGE_STARTED_AT_KEY",
|
|
90
|
+
"MFA_CHALLENGE_MAX_ATTEMPTS",
|
|
91
|
+
"MFA_CHALLENGE_WINDOW_SECONDS",
|
|
92
|
+
"MFA_REVALIDATION_USER_ID_KEY",
|
|
93
|
+
"MFA_REVALIDATION_AT_KEY",
|
|
94
|
+
"MFA_REVALIDATION_MAX_ATTEMPTS",
|
|
95
|
+
"MFA_REVALIDATION_WINDOW_SECONDS",
|
|
96
|
+
# mfa — TOTP
|
|
97
|
+
"create_totp_factor",
|
|
98
|
+
"confirm_totp_factor",
|
|
99
|
+
"verify_totp_code",
|
|
100
|
+
"totp_provisioning_uri",
|
|
101
|
+
"generate_totp_secret",
|
|
102
|
+
"validate_mfa_factor_contract",
|
|
103
|
+
"normalize_mfa_factor",
|
|
104
|
+
"is_valid_mfa_factor",
|
|
105
|
+
"is_mfa_factor_active",
|
|
106
|
+
"is_mfa_enabled",
|
|
107
|
+
# mfa — challenge
|
|
108
|
+
"start_mfa_challenge",
|
|
109
|
+
"has_pending_mfa_challenge",
|
|
110
|
+
"get_mfa_challenge_user_id",
|
|
111
|
+
"clear_mfa_challenge",
|
|
112
|
+
"verify_mfa_challenge",
|
|
113
|
+
# mfa — revalidation
|
|
114
|
+
"mark_mfa_revalidated",
|
|
115
|
+
"has_recent_mfa_revalidation",
|
|
116
|
+
"get_mfa_revalidated_user_id",
|
|
117
|
+
"clear_mfa_revalidation",
|
|
118
|
+
"verify_mfa_revalidation",
|
|
119
|
+
"require_recent_mfa",
|
|
120
|
+
# recovery
|
|
121
|
+
"AuthMfaRecoveryCode",
|
|
122
|
+
"RecoveryCodesSetup",
|
|
123
|
+
"generate_recovery_code",
|
|
124
|
+
"normalize_recovery_code",
|
|
125
|
+
"hash_recovery_code",
|
|
126
|
+
"verify_recovery_code",
|
|
127
|
+
"create_recovery_codes",
|
|
128
|
+
"consume_recovery_code",
|
|
129
|
+
"validate_recovery_code_contract",
|
|
130
|
+
"normalize_recovery_code_record",
|
|
131
|
+
"is_valid_recovery_code_record",
|
|
132
|
+
# secret_crypto
|
|
133
|
+
"encrypt_totp_secret",
|
|
134
|
+
"decrypt_totp_secret",
|
|
135
|
+
"MfaSecretKeyMissing",
|
|
136
|
+
"MfaSecretInvalidKey",
|
|
137
|
+
"MfaSecretNotEncrypted",
|
|
138
|
+
# totp_replay
|
|
139
|
+
"is_replay",
|
|
140
|
+
"record_used",
|
|
141
|
+
"purge_old",
|
|
142
|
+
"purge_all_totp_replay",
|
|
143
|
+
"step_for_time",
|
|
144
|
+
]
|