- FastAPI backend with JWT authentication - ElGamal, RSA-PSS, ZK-proofs crypto modules - HTML5/JS frontend SPA - MariaDB database with 5 tables - Docker Compose with 3 services (frontend, backend, mariadb) - Comprehensive tests for cryptography - Typst technical report (30+ pages) - Makefile with development commands
304 lines
6.7 KiB
Markdown
304 lines
6.7 KiB
Markdown
# Guide de Contribution
|
|
|
|
## Organisation du Code
|
|
|
|
```
|
|
e-voting-system/
|
|
├── src/
|
|
│ ├── backend/ # API FastAPI
|
|
│ │ ├── main.py # Point d'entrée
|
|
│ │ ├── config.py # Configuration
|
|
│ │ ├── models.py # Modèles SQLAlchemy
|
|
│ │ ├── schemas.py # Schémas Pydantic
|
|
│ │ ├── auth.py # Authentification
|
|
│ │ ├── services.py # Logique métier
|
|
│ │ ├── dependencies.py # DI FastAPI
|
|
│ │ ├── database.py # Configuration BD
|
|
│ │ └── routes/ # Routes API
|
|
│ │ ├── auth.py
|
|
│ │ ├── elections.py
|
|
│ │ ├── votes.py
|
|
│ │ └── __init__.py
|
|
│ ├── crypto/ # Primitives cryptographiques
|
|
│ │ ├── __init__.py
|
|
│ │ ├── encryption.py # ElGamal, AES
|
|
│ │ ├── signatures.py # RSA-PSS
|
|
│ │ ├── zk_proofs.py # Fiat-Shamir
|
|
│ │ └── hashing.py # SHA-256
|
|
│ └── frontend/ # Interface web
|
|
│ └── index.html # SPA HTML5
|
|
├── tests/ # Tests
|
|
│ ├── test_crypto.py
|
|
│ ├── test_backend.py # À créer
|
|
│ ├── conftest.py
|
|
│ └── __init__.py
|
|
├── docker/ # Configuration Docker
|
|
│ ├── Dockerfile.backend
|
|
│ ├── Dockerfile.frontend
|
|
│ └── init.sql
|
|
├── rapport/ # Documentation (Typst)
|
|
│ └── main.typ
|
|
├── pyproject.toml # Dépendances Python
|
|
├── docker-compose.yml # Orchestration
|
|
├── Makefile # Commandes de dev
|
|
├── README.md # Ce fichier
|
|
└── .gitignore
|
|
```
|
|
|
|
## Standards de Code
|
|
|
|
### Style Python
|
|
|
|
- **Formatage** : Black (88 chars de limite)
|
|
- **Linting** : Ruff
|
|
- **Type Hints** : Obligatoires pour les fonctions publiques
|
|
- **Docstrings** : Google style
|
|
|
|
```python
|
|
def create_voter(db: Session, voter: schemas.VoterRegister) -> models.Voter:
|
|
"""
|
|
Créer un nouvel électeur.
|
|
|
|
Args:
|
|
db: Session de base de données
|
|
voter: Données d'enregistrement
|
|
|
|
Returns:
|
|
Voter créé
|
|
|
|
Raises:
|
|
ValueError: Si l'email existe déjà
|
|
"""
|
|
pass
|
|
```
|
|
|
|
### Naming Conventions
|
|
|
|
- **Classes** : PascalCase (`VoterService`, `ElGamalEncryption`)
|
|
- **Functions** : snake_case (`get_voter_by_email()`)
|
|
- **Constants** : UPPER_CASE (`DB_HOST`, `MAX_RETRIES`)
|
|
- **Private** : Prefix underscore (`_internal_function()`)
|
|
|
|
### Tests
|
|
|
|
- Fichiers : `test_*.py`
|
|
- Fonctions : `test_*_scenario()`
|
|
- Assertions claires : `assert result == expected`
|
|
- Coverage : Minimum 80%
|
|
|
|
## Git Workflow
|
|
|
|
### Branches
|
|
|
|
- `main` : Code stable
|
|
- `dev` : Développement en cours
|
|
- `feature/*` : Nouvelles fonctionnalités
|
|
- `bugfix/*` : Corrections
|
|
- `doc/*` : Documentation
|
|
|
|
### Commits
|
|
|
|
Format :
|
|
```
|
|
[TYPE] Titre du commit
|
|
|
|
Description détaillée si nécessaire.
|
|
|
|
- Point 1
|
|
- Point 2
|
|
|
|
Fixes #123
|
|
```
|
|
|
|
Types :
|
|
- `[FEAT]` : Nouvelle fonctionnalité
|
|
- `[FIX]` : Correction de bug
|
|
- `[DOCS]` : Documentation
|
|
- `[REFACTOR]` : Restructuration
|
|
- `[TEST]` : Tests
|
|
- `[CHORE]` : Maintenance
|
|
|
|
### Pull Requests
|
|
|
|
1. Créer une branche depuis `dev`
|
|
2. Faire les changements
|
|
3. Écrire des tests
|
|
4. Formater le code : `make format`
|
|
5. Vérifier les lints : `make lint`
|
|
6. Commiter avec messages clairs
|
|
7. Ouvrir une PR sur `dev`
|
|
8. Review + merge
|
|
|
|
## Développement Local
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
make install
|
|
cp .env.example .env
|
|
make up
|
|
```
|
|
|
|
### Développement
|
|
|
|
```bash
|
|
# Terminal 1 : Backend
|
|
make dev
|
|
|
|
# Terminal 2 : Logs
|
|
make logs
|
|
|
|
# Terminal 3 : Tests
|
|
make test
|
|
```
|
|
|
|
### Avant de commit
|
|
|
|
```bash
|
|
make format # Formater
|
|
make lint # Vérifier
|
|
make test # Tester
|
|
```
|
|
|
|
## Ajouter une Nouvelle Fonctionnalité
|
|
|
|
### Exemple : Authentification multi-facteur (MFA)
|
|
|
|
1. **Design** : Planifier l'architecture
|
|
- Comment stocker les secrets 2FA ?
|
|
- QR codes ou SMS ?
|
|
- Récupération ?
|
|
|
|
2. **Backend** :
|
|
- Ajouter colonne `mfa_secret` à `voters`
|
|
- Créer endpoints `/auth/mfa/enable` et `/auth/mfa/verify`
|
|
- Tests dans `test_backend.py`
|
|
|
|
3. **Frontend** :
|
|
- Ajouter Vue MFA dans `index.html`
|
|
- Intégrer lib de QR code
|
|
|
|
4. **Documentation** :
|
|
- Mettre à jour `DEPLOYMENT.md`
|
|
- Commenter le code
|
|
|
|
5. **Tests** :
|
|
- Tests unitaires du MFA
|
|
- Tests d'intégration login+MFA
|
|
|
|
6. **PR** :
|
|
- Décrire les changements
|
|
- Lier les issues
|
|
- Demander review
|
|
|
|
## Sécurité
|
|
|
|
### Checklist de Sécurité
|
|
|
|
- [ ] Pas de secrets en dur (utiliser `.env`)
|
|
- [ ] Validation des entrées (Pydantic)
|
|
- [ ] Authentification sur tous les endpoints privés
|
|
- [ ] Rate limiting si applicable
|
|
- [ ] CORS restrictif
|
|
- [ ] Logs pas de données sensibles
|
|
- [ ] Dépendances à jour (check CVE)
|
|
|
|
### Dépendances
|
|
|
|
```bash
|
|
# Vérifier les vulnérabilités
|
|
poetry audit
|
|
|
|
# Mettre à jour
|
|
poetry update
|
|
```
|
|
|
|
## Documentation
|
|
|
|
### Code
|
|
|
|
```python
|
|
def homomorphic_add(a: Ciphertext, b: Ciphertext, p: int) -> Ciphertext:
|
|
"""
|
|
Additionner deux ciphertexts ElGamal.
|
|
|
|
L'addition homomorphe ElGamal: E(m1) * E(m2) = E(m1 + m2)
|
|
|
|
Mathématiquement:
|
|
c1_sum = (a.c1 * b.c1) mod p
|
|
c2_sum = (a.c2 * b.c2) mod p
|
|
|
|
Cette propriété est cruciale pour le dépouillement sécurisé.
|
|
|
|
Example:
|
|
>>> vote1 = eg.encrypt(pk, 1)
|
|
>>> vote2 = eg.encrypt(pk, 0)
|
|
>>> total = homomorphic_add(vote1, vote2, p)
|
|
>>> result = eg.decrypt(sk, total, p)
|
|
>>> assert result == 1
|
|
"""
|
|
pass
|
|
```
|
|
|
|
### Rapports
|
|
|
|
Tous les rapports vont dans `rapport/` en `.typ` (Typst)
|
|
|
|
- Inclure diagrams et formules
|
|
- Citer les sources
|
|
- Expliquer les choix
|
|
|
|
## Performance
|
|
|
|
### Profiling
|
|
|
|
```python
|
|
import cProfile
|
|
cProfile.run('function_to_profile()', sort='cumulative')
|
|
```
|
|
|
|
### Benchmarks
|
|
|
|
```bash
|
|
# Exemple de benchmark
|
|
time poetry run python -m pytest tests/test_crypto.py::TestElGamalEncryption -v
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Erreur d'import
|
|
|
|
```python
|
|
# ❌ Mauvais
|
|
from .models import Voter
|
|
from .services import VoterService
|
|
|
|
# ✅ Bon (depuis backend/)
|
|
from backend.models import Voter
|
|
from backend.services import VoterService
|
|
```
|
|
|
|
### Type hints
|
|
|
|
```python
|
|
# ❌ Mauvais
|
|
def get_voters(db):
|
|
return db.query(models.Voter).all()
|
|
|
|
# ✅ Bon
|
|
def get_voters(db: Session) -> List[models.Voter]:
|
|
return db.query(models.Voter).all()
|
|
```
|
|
|
|
## Ressources
|
|
|
|
- [FastAPI Docs](https://fastapi.tiangolo.com/)
|
|
- [SQLAlchemy ORM](https://docs.sqlalchemy.org/)
|
|
- [Pydantic Validation](https://docs.pydantic.dev/)
|
|
- [Python Cryptography](https://cryptography.io/)
|
|
- [Typst Docs](https://typst.app/)
|
|
|
|
## Questions ?
|
|
|
|
Consultez le rapport technique : `rapport/main.typ`
|