No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-10 19:38:27 +02:00
gradle/wrapper First commit 2026-09-09 18:30:47 +02:00
src Add token generation to download file, and antivirus check 2026-09-10 19:38:27 +02:00
.gitattributes First commit 2026-09-09 18:30:47 +02:00
.gitignore First commit 2026-09-09 18:30:47 +02:00
build.gradle First commit 2026-09-09 18:30:47 +02:00
gradlew First commit 2026-09-09 18:30:47 +02:00
gradlew.bat First commit 2026-09-09 18:30:47 +02:00
README.md Add token generation to download file, and antivirus check 2026-09-10 19:38:27 +02:00
settings.gradle First commit 2026-09-09 18:30:47 +02:00

Ce dépôt contient le résultat d'un exercice consistant à réaliser un microservice d'envoi de fichier utilisant un scan antivirus pour vérifier ces derniers.

Hypothèses et limitations :

  • Pour simplifier, je suis parti du principe que le service antivirus avait accès au fichier et pouvait y accéder via un identifiant (ici, le chemin du fichier).
  • De même, pour simplifier, j'ai simplement considéré que le service renvoyait 200 si le fichier était bon, et 500 sinon. Dans un cas réel il faudrait surement parser la réponse et faire plus de vérifications.
  • Les fichiers sont stockés simplement sur le système de fichier du serveur.
  • Je n'ai pas configuré la connexion à une base de données réelle comme PostgreSQL, j'ai simplement utilisé la base de données H2 en mémoire.

Description de la solution :

On se base sur un service de type REST dont les routes sont :

  • "/upload" qui attend un fichier, l'enregistre sur la base de données et le stocke sur le système de fichier local.
  • "/file" qui permet de récupérer les informations d'un fichier.
  • "/download" qui permet de récupérer le fichier.

On s'assure d'avoir un identifiant unique pour le fichier (ici, filepath qui est le chemin du fichier) en interrogeant la base de données. Pour vérifier que ce chemin est bien généré (et qu'on filtre le nom du fichier pour éviter les failles de sécurité), j'ai écrit des tests unitaires (voir la classe SaveFileMetadataServiceImplTest).

Pour ne pas gérer des utilisateurs et des permissions et économiser du temps, j'ai choisi une solution simple pour l'accès au fichier : je génère un token aléatoire via SecureRandom() que l'utilisateur doit fournir pour lire le fichier.

Pour l'implémentation de l'analyse de l'antivirus, je suis parti du principe que l'analyse pouvait durer longtemps. L'appel à l'antivirus se fait via une méthode asynchrone pour que /upload redonne tout de suite la main. Le statut du fichier est initialisé à "AWAITING", puis selon la réponse du service web, il est mis à jour. On peut vérifier le statut en appelant /file. L'appel à /download renverra une erreur tant que le statut du fichier n'est pas validé.

Utilisation du projet :

Dans application.properties, changer :

  • fr.artlef.filetransfer.storage.folder vers un dossier existant dans lequel l'application va stocker les fichiers.
  • fr.artlef.filetransfer.antivirus.url vers une url à appeler qui renvoie 200 si le fichier est bon et 500 sinon.

Lancer ./gradlew bootRun.

upload un fichier sur localhost:8080 sur /upload, exemple avec curl :

curl -X POST -F "file=@test.png"  http://localhost:8080/upload
{"filename":"test.png","token":"3h043ioaLqz1FaaGp6np1j5WpEfHIXlzZRrO1MGVCKu1NxZPUQ_yKO6xGYzVn-RIj0Lloz8wAmykJwoxELjO_A=="}

Utiliser le token pour récupérer les informations sur le fichier.

curl "http://localhost:8080/file?token=3h043ioaLqz1FaaGp6np1j5WpEfHIXlzZRrO1MGVCKu1NxZPUQ_yKO6xGYzVn-RIj0Lloz8wAmykJwoxELjO_A=="
{"filename":"test.png","antivirusCheckStatus":"SUCCESS"}

Utiliser le token pour récupérer le fichier.

curl "http://localhost:8080/download?token=3h043ioaLqz1FaaGp6np1j5WpEfHIXlzZRrO1MGVCKu1NxZPUQ_yKO6xGYzVn-RIj0Lloz8wAmykJwoxELjO_A==" > test.png

Possibilités d'évolutions :

  • Je n'aime pas le fait d'avoir appelé la classe "File", mais donner un autre nom pourrait aussi porter à confusion...
  • Améliorer les interfaces "FileStorage" et ajouter des implémentations spécifiques à d'autres systèmes de stockage de fichier comme amazon S3.
  • Déterminer une extension quand on doit générer un nom de fichier.
  • Valider l'url de connexion au service antivirus au démarrage de l'application.