Cahier de tests exhaustif — PD-63¶
Endpoint : GET /documents/:id/download
Préconditions générales¶
- Environnements de test disponibles : OVH Object Storage et AWS Glacier (mock/stub signé + sandbox réel).
- Jeu de données minimal :
- Tenant A :
ownerA,delegateA,b2bA,docA_active,docA_deleted,docA_locked. - Tenant B :
ownerB,docB_active. - Auth supportée : JWT signé serveur (valide, expiré, falsifié).
- Horloge testable (fake clock) pour vérifier TTL 5 minutes.
- Audit store consultable (event sink ou table
audit_events).
1) Tests unitaires¶
| ID | Type | Références | Given | When | Then |
|---|---|---|---|---|---|
| TC-NOM-01 | Unitaire | INV-63-10 | Un documentId UUID/ULID valide | Validation d'entrée exécutée | L'ID est accepté, aucune erreur |
| TC-ERR-01 | Unitaire | INV-63-10 | Un documentId mal formé (' OR 1=1 --, vide, trop long) | Validation d'entrée exécutée | Erreur normalisée 400, sans détail sensible |
| TC-NOM-02 | Unitaire | CA-63-01, INV-63-08 | Utilisateur authentifié owner du document | Évaluation des droits | Décision ALLOW (owner) |
| TC-NOM-03 | Unitaire | CA-63-09, INV-63-08 | Utilisateur avec délégation active | Évaluation des droits | Décision ALLOW (partage) |
| TC-NOM-04 | Unitaire | CA-63-09, INV-63-08 | Utilisateur B2B co-détenteur | Évaluation des droits | Décision ALLOW (B2B) |
| TC-ERR-02 | Unitaire | CA-63-03, INV-63-08 | Utilisateur authentifié sans droit explicite | Évaluation des droits | Décision DENY → 403 |
| TC-ERR-03 | Unitaire | CA-63-04, INV-63-06 | Droit marqué révoqué | Évaluation des droits | Décision DENY immédiate → 403 |
| TC-NOM-05 | Unitaire | CA-63-05, INV-63-03 | Requête autorisée | Génération URL pré-signée | TTL fixé strictement à 300s |
| TC-SEC-01 | Unitaire | CA-63-06, INV-63-02 | Contexte de signature complet | Construction payload de réponse | Aucune clé (K_doc, K_master, dérivées) n'est incluse |
| TC-SEC-02 | Unitaire | CA-63-06, INV-63-02, INV-63-10 | Erreur technique simulée | Sérialisation erreur + logging | Logs/réponse redacted, aucun secret exposé |
| TC-NOM-06 | Unitaire | CA-63-07, INV-63-05 | Toute demande (allow/deny) | Construction événement probatoire | Événement contient actor, docId, tenant, décision, timestamp |
| TC-NOM-07 | Unitaire | CA-63-08, INV-63-09 | Requête download | Exécution handler | Aucune commande de mutation WORM/contenu n'est émise |
2) Tests d'intégration¶
| ID | Type | Références | Given | When | Then |
|---|---|---|---|---|---|
| TC-INT-01 | Intégration | CA-63-01, CA-63-07 | ownerA authentifié, docA_active | GET /documents/:id/download | 200 + URL pré-signée + audit créé |
| TC-INT-02 | Intégration | CA-63-09, CA-63-07 | delegateA avec délégation valide | Appel endpoint | 200 + URL + audit avec contexte délégation |
| TC-INT-03 | Intégration | CA-63-09, CA-63-07 | b2bA co-détention valide | Appel endpoint | 200 + URL + audit B2B |
| TC-INT-04 | Intégration | CA-63-02, INV-63-04, INV-63-05 | Aucune auth | Appel endpoint | 401, pas d'URL, événement probatoire de rejet |
| TC-INT-05 | Intégration | CA-63-04, INV-63-06 | Droit révoqué juste avant appel | Appel endpoint | 403 immédiat, aucune URL émise |
| TC-INT-06 | Intégration | INV-63-10 | Utilisateur autorisé, doc inexistant | Appel endpoint | 404, corps neutre, audit rejet |
| TC-INT-07 | Intégration | INV-63-10 | Utilisateur autorisé, doc supprimé logique | Appel endpoint | 410, corps neutre |
| TC-INT-08 | Intégration | INV-63-10 | Utilisateur autorisé, doc verrouillé | Appel endpoint | 423, corps neutre |
| TC-INT-09 | Intégration | INV-63-07, INV-63-10 | Storage provider indisponible | Appel endpoint | 503, aucune donnée sensible |
| TC-INT-10 | Intégration | INV-63-10 | Exception interne non prévue | Appel endpoint | 500 générique, trace technique interne seulement |
| TC-INT-11 | Intégration | CA-63-10, INV-63-07 | Provider=OVH | Exécution suite nominale/erreur | Codes/statut/TTL identiques au contrat |
| TC-INT-12 | Intégration | CA-63-10, INV-63-07 | Provider=AWS Glacier | Exécution suite nominale/erreur | Codes/statut/TTL identiques au contrat |
| TC-INT-13 | Intégration | CA-63-08, INV-63-09 | Snapshot métadonnées WORM avant appel | Appel endpoint puis relecture | Aucune altération (contentHash, flags WORM inchangés) |
| TC-INT-14 | Intégration | CA-63-07, INV-63-05 | Service audit indisponible | Appel endpoint autorisé | Requête rejetée en fail-closed (ERR-63-11), aucun accès délivré |
| TC-INT-15 | Intégration | CA-63-05, INV-63-03 | URL générée à T0 | Utilisation URL à T0+301s | Accès refusé (expiration effective TTL) |
3) Tests E2E¶
| ID | Type | Références | Given | When | Then |
|---|---|---|---|---|---|
| TC-E2E-01 | E2E | CA-63-01, CA-63-05 | ownerA connecté | Demande URL puis téléchargement < 5 min | Téléchargement réussi, audit présent |
| TC-E2E-02 | E2E | CA-63-09 | delegateA connecté, délégation active | Demande URL puis téléchargement | Succès identique au flux owner (hors contexte audit) |
| TC-E2E-03 | E2E | CA-63-09 | b2bA connecté, co-détention active | Demande URL puis téléchargement | Succès flux B2B + audit B2B |
| TC-E2E-04 | E2E | CA-63-03, INV-63-08 | Utilisateur tenant B sur doc tenant A | Appel endpoint | 403, aucune fuite inter-tenant |
| TC-E2E-05 | E2E | CA-63-05, INV-63-03 | URL obtenue | Attendre >5 min puis utiliser URL | Échec d'accès (URL expirée) |
| TC-E2E-06 | E2E | CA-63-04, INV-63-06 | Droit valide puis révoqué | Nouvelle demande après révocation | 403 immédiat |
| TC-E2E-07 | E2E | CA-63-10, INV-63-07 | Même scénario rejoué OVH puis AWS | Exécution batch E2E | Résultats fonctionnels homogènes |
| TC-E2E-08 | E2E | CA-63-07, INV-63-05 | 3 demandes successives (owner/partage/B2B) | Exécution complète | 3 événements probatoires distincts et corrélables |
4) Tests de sécurité¶
| ID | Type | Références | Given | When | Then |
|---|---|---|---|---|---|
| TC-SEC-10 | Sécurité | INV-63-10 | Payload ID avec SQL/NoSQL/path injection | Appel endpoint | 400 sans stacktrace ni détail interne |
| TC-SEC-11 | Sécurité | INV-63-08, INV-63-10 | Utilisateur non autorisé, doc existant vs inexistant | Appels répétés | Réponses anti-énumération conformes à la politique (pas d'info exploitable) |
| TC-SEC-12 | Sécurité | INV-63-08 | Campagne timing (N>=500) sur IDs existants/non-existants sans droits | Mesure latence p95/p99 | Écart latence p95 ≤ 15% entre doc existant et inexistant |
| TC-SEC-13 | Sécurité | CA-63-03, INV-63-08 | Token tenant A, doc tenant B | Appel endpoint | 403, aucune URL, audit rejet |
| TC-SEC-14 | Sécurité | CA-63-02, INV-63-04 | JWT signature invalidée | Appel endpoint | 401 |
| TC-SEC-15 | Sécurité | CA-63-02, INV-63-04 | JWT expiré/replay | Appel endpoint | 401, aucune URL |
| TC-SEC-16 | Sécurité | CA-63-06, INV-63-02 | Scan corps, headers, logs, traces | Exécution flux nominal + erreurs | Aucune occurrence de K_doc, K_master, secrets dérivés |
| TC-SEC-17 | Sécurité | INV-63-01, INV-63-02 | Instrumentation serveur activée | Appel endpoint et téléchargement client | Serveur n'accède jamais au contenu clair, seulement émission URL signée |
| TC-SEC-18 | Sécurité | INV-63-10 | Déclenchement 500/503 forcé | Appel endpoint | Messages d'erreur génériques, aucune fuite infra/cloud/provider interne |
5) Matrice de traçabilité (TC → CA/INV)¶
| Test Case | Liens |
|---|---|
| TC-NOM-01 | INV-63-10 |
| TC-ERR-01 | INV-63-10 |
| TC-NOM-02 | CA-63-01, INV-63-08 |
| TC-NOM-03 | CA-63-09, INV-63-08 |
| TC-NOM-04 | CA-63-09, INV-63-08 |
| TC-ERR-02 | CA-63-03, INV-63-08 |
| TC-ERR-03 | CA-63-04, INV-63-06 |
| TC-NOM-05 | CA-63-05, INV-63-03 |
| TC-SEC-01 | CA-63-06, INV-63-02 |
| TC-SEC-02 | CA-63-06, INV-63-02, INV-63-10 |
| TC-NOM-06 | CA-63-07, INV-63-05 |
| TC-NOM-07 | CA-63-08, INV-63-09 |
| TC-INT-01 | CA-63-01, CA-63-07 |
| TC-INT-02 | CA-63-09, CA-63-07 |
| TC-INT-03 | CA-63-09, CA-63-07 |
| TC-INT-04 | CA-63-02, INV-63-04, INV-63-05 |
| TC-INT-05 | CA-63-04, INV-63-06 |
| TC-INT-06 | INV-63-10 |
| TC-INT-07 | INV-63-10 |
| TC-INT-08 | INV-63-10 |
| TC-INT-09 | INV-63-07, INV-63-10 |
| TC-INT-10 | INV-63-10 |
| TC-INT-11 | CA-63-10, INV-63-07 |
| TC-INT-12 | CA-63-10, INV-63-07 |
| TC-INT-13 | CA-63-08, INV-63-09 |
| TC-INT-14 | CA-63-07, INV-63-05 |
| TC-INT-15 | CA-63-05, INV-63-03 |
| TC-E2E-01 | CA-63-01, CA-63-05 |
| TC-E2E-02 | CA-63-09 |
| TC-E2E-03 | CA-63-09 |
| TC-E2E-04 | CA-63-03, INV-63-08 |
| TC-E2E-05 | CA-63-05, INV-63-03 |
| TC-E2E-06 | CA-63-04, INV-63-06 |
| TC-E2E-07 | CA-63-10, INV-63-07 |
| TC-E2E-08 | CA-63-07, INV-63-05 |
| TC-SEC-10 | INV-63-10 |
| TC-SEC-11 | INV-63-08, INV-63-10 |
| TC-SEC-12 | INV-63-08 |
| TC-SEC-13 | CA-63-03, INV-63-08 |
| TC-SEC-14 | CA-63-02, INV-63-04 |
| TC-SEC-15 | CA-63-02, INV-63-04 |
| TC-SEC-16 | CA-63-06, INV-63-02 |
| TC-SEC-17 | INV-63-01, INV-63-02 |
| TC-SEC-18 | INV-63-10 |
Généré par : ChatGPT (OpenCode, gpt-5.3-codex) Date : 2026-02-20 Version : v2 — Corrections Gate 3 v1