Files
xamxam/apps/admin/README.md
Théophile Gervreau-Mercier 467aced734 Restructure repository and implement secure search feature
Phase 1: Consolidate shared infrastructure
- Create shared/ directory for common code
- Consolidate Database.php from front-backend and formulaire into unified shared/Database.php
  - Smart path detection for test.db vs posterg.db
  - Secure search with wildcard escaping and input validation
  - Support both singleton and direct instantiation patterns
  - Full CRUD methods for admin functionality
- Move RateLimit.php to shared/ (30 requests/min)
- Update all require paths across apps to use shared/

Phase 2: Reorganize directory structure
- Rename front-backend/ → apps/public/
- Rename formulaire/ → apps/admin/
- Rename db/ → database/
- Update all file paths for new structure
- Create root .gitignore excluding databases, cache, logs

Implement secure search feature
- Add apps/public/search.php with full-text search across theses
- Search filters: query, year, orientation, AP program, keywords
- Security features:
  - SQL injection prevention (prepared statements)
  - Wildcard injection prevention (escape % and _)
  - Input validation (max 200 chars, year range 1900-2100)
  - Rate limiting (30 req/min per IP)
  - Pagination limited to 100 results/page
  - XSS protection (htmlspecialchars on output)

Add comprehensive test suite
- Create apps/public/tests/ with proper structure
  - tests/Integration/SearchTest.php - 12 search scenarios
  - tests/Security/SecurityTest.php - vulnerability testing
  - tests/Unit/RateLimitTest.php - rate limit behavior
- Create database/fixtures/CreateTestDatabase.php
- Add apps/public/run-tests.php test runner
- All tests passing (4/4 suites)

Update deployment configuration
- Rename justfile 'sync' recipe to 'deploy'
- Create deploy group with separate deploy-public and deploy-admin
- Add test-deploy recipe for test database
- Exclude *.db, tests/, cache/, *.md from production deploy
- Deploy shared/ to both public and admin locations

Stats: +4482 insertions, -654 deletions across 72 files
2026-02-02 18:53:58 +01:00

278 lines
7.0 KiB
Markdown

# PostERG - Formulaire d'ajout de mémoires
Le formulaire permet aux étudiant.e.s sortant de l'ERG en cursus de Master de soumettre leurs mémoires et travaux de fin d'études.
## Fonctionnalités
- Soumission de mémoires avec métadonnées complètes
- Stockage structuré dans base de données SQLite
- Support multi-auteurs, multi-superviseurs, multi-langues
- Gestion des mots-clés (max 10 par TFE)
- Téléversement sécurisé des fichiers
- Protection CSRF et validation complète
- Workflow de publication (soumission → soutenance → publication)
## Technologies
- PHP 7.4+ avec PDO SQLite
- SQLite 3.8+
- CSS fait-main + [Simple.css](https://simplecss.org/)
- [Symfony YAML](https://symfony.com/doc/current/components/yaml.html) (pour migration legacy)
- [Just](https://github.com/casey/just) pour les tâches de développement
## Installation
### Prérequis
```bash
# PHP avec SQLite
php -v # 7.4 ou supérieur
php -m | grep sqlite # Vérifier extension SQLite
# Composer
composer install
# Just (optionnel mais recommandé)
# macOS: brew install just
# Linux: cargo install just
```
### Configuration
1. **Base de données production:**
```bash
cd ../db
sqlite3 posterg.db < schema.sql
```
2. **Base de données de test:**
```bash
just init-test-db
```
## Développement local
### Avec Just (recommandé)
```bash
# Configuration complète et lancement du serveur
just dev
# Ou étape par étape:
just init-test-db # Créer la base de test
just serve # Lancer le serveur (réinitialise la DB)
just serve-only # Lancer sans réinitialiser
# Nettoyage
just cleanup # Supprimer test.db et fichiers uploadés
just reset # Cleanup + réinitialisation
# Statistiques
just stats # Voir les stats de la DB
just recent # Voir les soumissions récentes
just show 1 # Voir le TFE #1
# Autres commandes
just query # Shell SQLite interactif
just dump # Backup de la DB
```
### Sans Just
```bash
# Créer la base de test
sqlite3 test.db < ../db/schema.sql
# Lancer le serveur
php -S 127.0.0.1:3000
# Ouvrir dans le navigateur
open http://127.0.0.1:3000
```
## Structure du projet
```
formulaire/
├── assets/ # CSS et ressources
│ ├── normalize.css
│ ├── simple.css
│ ├── posterg.css
│ └── icon.svg
├── data/ # Données (gitignored)
│ ├── theses/ # Fichiers TFE uploadés
│ ├── covers/ # Images de couverture
│ └── yaml/ # Legacy YAML (migration)
├── Database.php # Classe helper pour DB
├── index.php # Formulaire de soumission
├── formulaire.php # Traitement de soumission
├── thanks.php # Page de confirmation
├── justfile # Tâches de développement
├── .gitignore # Fichiers ignorés
├── MIGRATION.md # Guide de migration YAML → SQLite
├── SECURITY.md # Documentation sécurité
└── README.md # Ce fichier
```
## Workflow de soumission
1. **Étudiant remplit le formulaire** (index.php)
- Informations de base (nom, année, titre)
- Détails académiques (orientation, AP, finalité)
- Contenu (synopsis, mots-clés, langues, formats)
- Upload fichiers (TFE + annexes)
2. **Validation et traitement** (formulaire.php)
- Validation CSRF token
- Sanitization des entrées
- Transaction DB (all-or-nothing)
- Création/liaison entités (auteur, superviseurs, mots-clés)
- Upload sécurisé avec noms aléatoires
- Génération identifiant unique (YYYY-NNN)
3. **Confirmation** (thanks.php)
- Affichage récapitulatif
- Statut: "En attente de publication"
- Liste des fichiers uploadés
4. **Publication** (admin - à venir)
- Après soutenance
- Ajout note contextuelle du jury (optionnel)
- Points du jury
- Publication publique
## Base de données
### Structure
- **19 tables** incluant tables de jonction et vues
- **Normalized 3NF** avec clés étrangères
- **Timestamps automatiques** via triggers
- **Cascade deletes** pour intégrité référentielle
### Tables principales
- `theses` - TFE avec métadonnées
- `authors` - Auteurs (réutilisables)
- `supervisors` - Promoteurs
- `thesis_files` - Métadonnées fichiers
- `keywords` - Mots-clés (extensible)
- Plus tables de référence et jonctions
### Vues
- `v_theses_full` - Vue complète pour admin
- `v_theses_public` - Vue filtrée pour public
Voir `../db/README.md` pour documentation complète.
## Sécurité
✅ **Protection CSRF** - Tokens de session
✅ **SQL Injection** - Prepared statements PDO
✅ **Path Traversal** - Validation stricte des chemins
✅ **File Upload** - Noms aléatoires, validation MIME
✅ **Input Validation** - Sanitization + validation typage
✅ **Error Handling** - Pas d'exposition de chemins système
Voir `SECURITY.md` pour détails complets.
## Tests
### Test manuel
1. Lancer serveur: `just dev`
2. Ouvrir http://127.0.0.1:3000
3. Remplir formulaire avec données test
4. Vérifier confirmation
5. Vérifier DB: `just stats` et `just recent`
### Checklist
- [ ] Form se charge sans erreurs
- [ ] Dropdowns peuplés depuis DB
- [ ] Validation champs requis fonctionne
- [ ] Upload fichiers réussit
- [ ] Transaction rollback sur erreur
- [ ] Page confirmation affiche données
- [ ] Identifiant unique généré (YYYY-NNN)
- [ ] Fichiers stockés avec noms aléatoires
## Migration données legacy
Si vous avez des fichiers YAML existants:
```bash
# Script de migration à créer
php migrate_yaml_to_sqlite.php
```
Voir `MIGRATION.md` pour guide complet.
## Production
### Déploiement
1. **Copier fichiers:**
```bash
rsync -av --exclude='test.db' --exclude='data/' \
formulaire/ user@server:/var/www/posterg/
```
2. **Créer DB production:**
```bash
cd /var/www/posterg/db
sqlite3 posterg.db < schema.sql
```
3. **Permissions:**
```bash
chown -R www-data:www-data /var/www/posterg
chmod 644 db/posterg.db
chmod 755 data/theses data/covers
```
4. **Configuration nginx:**
```nginx
location /formulaire {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
}
}
```
### Backup
```bash
# Backup automatique quotidien
0 2 * * * sqlite3 /var/www/posterg/db/posterg.db \
.dump > /backups/posterg_$(date +\%Y\%m\%d).sql
```
## Support
- **Schema DB:** `../db/README.md`
- **Setup DB:** `../db/SETUP.md`
- **Sécurité:** `SECURITY.md`
- **Migration:** `MIGRATION.md`
- **Specs techniques:** `../db/posterg_fiche-technique.md`
## Changelog
### v2.0 - 2026-01-27
- Migration vers SQLite
- Support multi-entités (auteurs, superviseurs, etc.)
- Sécurité renforcée
- Workflow de publication
- Justfile pour développement
### v1.0 - Précédent
- Stockage YAML
- Formulaire basique