diff --git a/README.md b/README.md index 1b3245811197d068cd5eba584ad8b2c980aa026d..70ba3591ab4ca8583973078d088d632daf0857fd 100644 --- a/README.md +++ b/README.md @@ -12,22 +12,99 @@ Le projet a été construit à partir de Maven. Maven est installable via la lig Avant de pouvoir lancer le programme, il faut le compiler avec `mvn package`. -Le programme se lance ensuite en ligne de commande sans argument. +Le programme se lance ensuite en ligne de commande sans argument avec `mvn exec:java`. -Exemple d'utilisation : `mvn exec:java` +Au lancement du programme, `il faut enregistrer des serveurs FTP`. -Au lancement du programme, `un username et un password seront demandés` afin d'authentifier l'utilisateur. Si ceux-ci ne correspondent à aucun utilisateur autorisé à utiliser la plateforme, le programme le rejectera. +```sh +curl --request PUT 'http://localhost:8080/flopbox/{nom du serveur}' --header 'host:{nom de domaine}' + +Exemple : +curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com' +curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost' +``` + +A noter que pour `localhost`, il faudra lancer `un serveur FTP en local`. + +```sh +pip install --user pyftpdlib +python -m pyftpdlib # localhost:2121 user & pass:anonymous +``` + +Il est également possible d'`afficher les serveurs enregistrés` et de `les supprimer`. + +```sh +curl --request GET 'http://localhost:8080/flopbox/' +curl --request DELETE 'http://localhost:8080/flopbox/{nom du serveur}' + +Exemple : +curl --request GET 'http://localhost:8080/flopbox/' +curl --request DELETE 'http://localhost:8080/flopbox/ubuntu' +``` -Si les identifiants correspondent bien à un utilisateur autorisé à utiliser la plateforme, le programme lancera la plateforme à l'adresse `http://localhost:8080/myapp/`. +Une fois des serveurs enregistrés, il devient possible d'effectuer certaines opérations comme par exemple `lister un fichier ou un dossier distant`. + +```sh +curl --request GET 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' -Afin d'arrêter la plateforme, vous pouvez soit faire un `Ctrl+C` sur le terminal de lancement ou soit envoyer un signal `SIGKILL` au processus. Une solution permettant simplement d'écrire `stop` sur le terminal de lancement a été implémentée mais une exception au niveau du code généré lors de l'initialisation du projet, est levée empêchant cette solution de fonctionner. +Exemple : +curl --request GET 'http://localhost:8080/flopbox/ubuntu/' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous' +``` + +`Créer un dossier`. + +```sh +curl --request PUT 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du futur dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' + +Exemple : +curl --request PUT 'http://localhost:8080/flopbox/localhost/testFiles/dir_created' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous' +``` + +`Renommer un fichier ou un dossier`. + +```sh +curl --request PATCH 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'to:{nouveau nom du fichier ou dossier}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' + + +Exemple : +curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_rename' --header 'port:2121' --header 'to:dir_renamed' --header 'username:anonymous' --header 'password:anonymous' +``` + +`Supprimer un fichier ou un dossier`. + +```sh +curl --request DELETE 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier ou dossier}' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' + +Exemple : +curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme01.jpg' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous' +``` + +`Mettre en ligne un fichier`. + +```sh +curl --request POST 'http://localhost:8080/flopbox/{nom du serveur}/{nom du fichier mis en ligne}/upload' --header 'port:{numéro de port dentrée du serveur}' --header 'from:{chemin du fichier à mettre en ligne}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' + +Exemple : +curl --request POST 'http://localhost:8080/flopbox/localhost/meme_uploaded/upload' --header 'port:2121' --header 'from:testFiles/Lysithea_meme03.png' --header 'username:anonymous' --header 'password:anonymous' +``` + +`Télécharger un fichier`. + +```sh +curl --request GET 'http://localhost:8080/flopbox/{nom du serveur}/{chemin du fichier à télécharger}/download' --header 'port:{numéro de port dentrée du serveur}' --header 'username:{nom de compte}' --header 'password:{mot de passe}' + +Exemple : +curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html/download' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous' +``` + +Pour arrêter la plateforme proprement, vous pouvez simplement appuyer sur la touche `Entrée` de votre clavier. Sinon, vous pouvez faire un `Ctrl+C` sur le terminal de lancement ou bien envoyer un signal `SIGKILL` au processus. # Architecture Le projet a été construit à partir de Maven en utilisant la commande suivante : ```sh -mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=3.0.1 +mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=2.33 ``` L'archive du projet, après la compilation, est `target/flopbox-1.0-SNAPSHOT.jar`. @@ -38,154 +115,143 @@ Les tests se situent dans le dossier `src/test/java/flopbox` depuis la racine du Le projet contient les packages suivants : -- **account** -> Le package relatif aux comptes pouvant utiliser la plateforme +- **client** -> Le package relatif à l'initialisation du client et sa terminaison - **command** -> Le package relatif aux commandes utilisables par la plateforme -- **server** -> Le package relatif aux serveurs auxquels peut se connecter la plateforme - -# Commandes supportées - -La plateforme supporte les commandes curls suivantes : - -```curl -curl -v http://localhost:8080/myapp/myresource/cdup -curl -v http://localhost:8080/myapp/myresource/connect:{String address}:{int port} -curl -v http://localhost:8080/myapp/myresource/cwd:{String pathname} -curl -v http://localhost:8080/myapp/myresource/dele:{String pathname} -curl -v http://localhost:8080/myapp/myresource/list -curl -v http://localhost:8080/myapp/myresource/login:{String username}:{String password} -curl -v http://localhost:8080/myapp/myresource/mkd:{String pathname} -curl -v http://localhost:8080/myapp/myresource/pasv -curl -v http://localhost:8080/myapp/myresource/port -curl -v http://localhost:8080/myapp/myresource/pwd -curl -v http://localhost:8080/myapp/myresource/quit -curl -v http://localhost:8080/myapp/myresource/retr:{String pathname} -curl -v http://localhost:8080/myapp/myresource/rn:{String oldfilename}:{String newfilename} -curl -v http://localhost:8080/myapp/myresource/stor:{String pathname} -curl -v http://localhost:8080/myapp/myresource/type:{int type} -``` - -**Les informations entre crochets sont des variables à modifier dont le type a été indiqué pour plus de clarté.** - -Par exemple, pour se connecter au serveur ftp.ubuntu.com, la commande à utiliser est : - -```curl -curl -v http://localhost:8080/myapp/myresource/connect:ftp.ubuntu.com:21 -``` # Quelques exemples de code ```java /** - * Return if the password tried is the password of the account's username. + * Register a server and its host in the platform. * - * @param username The username registered. - * @param password The password tried. + * @param server The server. + * @param host The host of the server. * - * @return If the password tried is the password of the username's account. + * @return How the command went. */ -public static boolean isTheRightPassword(String username, String password) +public static String register(String server, String host) { - if(accounts.containsKey(username)) - return password.equals(accounts.get(username)); + if(servers.containsKey(server)) + return "The server \"" + server + "\" is already registered."; - else - return username.equals("anonymous"); + servers.put(server, host); + + return "The association \"" + server + " -> " + host + "\" has been registered."; } ``` -L'objet `accounts` est une `Map<String,String>` contenant les paires `<username,password>`. Cette fonction a un comportement similaire à celui des serveurs ftp. Elle vérifie tous les utilisateurs tentant de s'enregistrer auprès de la plateforme sauf `anonymous`. +La gestion des serveurs de la plateforme est très précise. `Le nom des fonctions dédiées à cet objectif représente bien ce qu'elles font`. Ici, l'enregistrement des serveurs sur la plateforme `n'empiète pas sur les autres serveurs` déjà enregistrés. Elle ne gagne donc pas en ambiguïté avec la fonction modify et `respecte bien le principe de responsabilité unique` (SRP). ```java /** - * Load the unique aliases in the program. + * Connect and log in the FTP server. + * + * @param client The FTP client. + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * + * @return True if the client could connect and log in the FTP server, otherwise false. */ -public static void loadAliases() +public static boolean connectAndLogin(FTPClient client, String server, int port, String username, String password) { - Map<String, String> aliases = Main.getAliases(); - try { - BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt)); + client.connect(ServerCommands.getServers().get(server), port); - String line; - while((line = reader.readLine()) != null) - { - int cut = line.indexOf(separator); - - String alias = line.substring(0, cut); - - /* If a same alias has already been put, we ignore it */ - if(aliases.containsKey(alias)) - continue; - - String server = line.substring(cut+1); - - aliases.put(alias, server); - } + if(FTPReply.isPositiveCompletion(client.getReplyCode())) + if(client.login(username, password)) + return client.setFileType(FTPClient.BINARY_FILE_TYPE); - reader.close(); + return false; } catch(IOException e) { - /* Do nothing */ + return false; } } ``` -Cette méthode `enregistre tous les alias uniques` des serveurs. Pour cela, elle va lire un fichier nommé `aliases.txt` à la racine du projet. `Pour ajouter ou modifier une association, c'est dans ce fichier que ça se passe.` Un système identique a été mis en place avec le fichier `accounts.txt` pour les `comptes autorisés à se connecter` à la plateforme. +`La connexion et identification est faite en premier` à chaque récupération de commande. `Le type binaire est également préféré` à celui de base, ascii, par soucis de compatibilité (de plus en plus de serveur le privilégie à l'instar d'ascii). ```java /** - * List the files of the working directory. + * List information about a file or files in a directory on the FTP server. * - * @param client The FTP client. + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param path The path of the file or directory. * - * @return How the command went. + * @return Information about the file or files in the directory. */ @GET -@Path("list") +@Path("{server}/{path:.*}") @Produces(MediaType.TEXT_PLAIN) -public String list(FTPClient client) +public String list(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username, @HeaderParam("password") String password, + @PathParam ("path" ) String path ) { - return LIST.execute(client); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.list(client, path); + ClientUtil.logoutAndDisconnect(client); + } + else + response = "The connection to the server failed."; + + + return response; } ``` -La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées avec @GET mais avec un @Path différent` afin de les différencier. +La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées` avec une méthode de requête HTTP et un chemin et `leur traitement se fait dans une autre classe`. Cette implémentation a l'avantage d'être `plus claire, plus maintenable et plus facilement débuggable`. ```java /** - * List the files of the working directory. + * List information about a file or files in a directory on the FTP server. * * @param client The FTP client. + * @param path The path of the file or directory. * - * @return How the command went. + * @return Information about the file or files in the directory. */ -public static String execute(FTPClient client) +public static String list(FTPClient client, String path) { String response = ""; try { - FTPFile[] files = client.listFiles(); + client.enterLocalPassiveMode(); + + FTPFile[] files = client.listFiles(path); for(FTPFile file : files) { - response += file.getName() + "\n"; + response += file.getRawListing(); + response += "\n"; } + + return response; } catch(IOException e) { - response = "The command \"" + NAME + "\" failed."; + response = "An IO error occured while sending the command or receiving its result."; } return response; } ``` -`Le traitement des commandes est effectué dans des classes propres` aux commandes dans le package `command`. Ce, afin que le code soit plus clair et mieux structuré. +Le traitement des commandes est effectué dans des `classes regroupant les commandes de par leur objectif` (gestion de la plateforme, FTP, etc...). Ces classes sont dans le package `command` et sont donc séparées de Main et MyResource par soucis de structuration. Elles doivent donc récupérer le client initialisé lors de la récupération des commandes. # Les tests @@ -193,10 +259,10 @@ Aucun test n'a été réalisé cette fois-ci. Les efforts ont été concentrés à rendre la plateforme fonctionnel. -# Ce que j'aurai amélioré avec le temps +# Ce que j'aurais amélioré avec le temps -J'aurais `mieux designé la gestion de l'authentification` auprès de la plateforme. +J'aurais `terminé la généralisation fichier-dossier des commandes` afin de toutes les rendre universelles. -J'aurais `expérimenté le multi-threading` de la plateforme. +J'aurais `expérimenté le postionnement des fonctions dans le répertoire courant du fichier ou dossier visé` afin de voir les avantages que cela aurait pu apporter (maintenabilité, clarté, etc...). -J'aurais `débuggé les communications plateforme-serveur` (malgré que j'y ai passé déjà plusieurs jours). \ No newline at end of file +J'aurais `rendu les retours encore plus précis` si une fonction n'avait pas rendu le résultat escompté. diff --git a/downloads/FOOTER.html b/downloads/FOOTER.html new file mode 100644 index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19 --- /dev/null +++ b/downloads/FOOTER.html @@ -0,0 +1,25 @@ +</div></div></div></div> +<footer class="p-footer"> + <div class="row"> + <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical + are registered trademarks of Canonical Ltd.</small></p> + <nav class="p-footer__nav"> + <ul class="p-footer__links"> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://www.ubuntu.com/legal"><small>Legal + information</small></a> + </li> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug"> + <small>Report a bug on this site</small></a> + </li> + </ul> + <span class="u-off-screen"> + <a href="#">Go to the top of the page</a> + </span> + </nav> + </div> +</footer> +</body></html> diff --git a/downloads/FOOTER_20210404_022313.html b/downloads/FOOTER_20210404_022313.html new file mode 100644 index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19 --- /dev/null +++ b/downloads/FOOTER_20210404_022313.html @@ -0,0 +1,25 @@ +</div></div></div></div> +<footer class="p-footer"> + <div class="row"> + <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical + are registered trademarks of Canonical Ltd.</small></p> + <nav class="p-footer__nav"> + <ul class="p-footer__links"> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://www.ubuntu.com/legal"><small>Legal + information</small></a> + </li> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug"> + <small>Report a bug on this site</small></a> + </li> + </ul> + <span class="u-off-screen"> + <a href="#">Go to the top of the page</a> + </span> + </nav> + </div> +</footer> +</body></html> diff --git a/downloads/FOOTER_20210404_022322.html b/downloads/FOOTER_20210404_022322.html new file mode 100644 index 0000000000000000000000000000000000000000..096978df4283c87cb9c81261f25a87966728dd19 --- /dev/null +++ b/downloads/FOOTER_20210404_022322.html @@ -0,0 +1,25 @@ +</div></div></div></div> +<footer class="p-footer"> + <div class="row"> + <p><small>© 2018 Canonical Ltd. Ubuntu and Canonical + are registered trademarks of Canonical Ltd.</small></p> + <nav class="p-footer__nav"> + <ul class="p-footer__links"> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://www.ubuntu.com/legal"><small>Legal + information</small></a> + </li> + <li class="p-footer__item"> + <a class="p-footer__link" + href="https://bugs.launchpad.net/ubuntu-cdimage/+filebug"> + <small>Report a bug on this site</small></a> + </li> + </ul> + <span class="u-off-screen"> + <a href="#">Go to the top of the page</a> + </span> + </nav> + </div> +</footer> +</body></html> diff --git a/downloads/README2.md b/downloads/README2.md new file mode 100644 index 0000000000000000000000000000000000000000..8927291b44a312449bb64e88f9ae691b6ba98e35 --- /dev/null +++ b/downloads/README2.md @@ -0,0 +1,202 @@ +# FlopBox + +Par <ins>**Rayane Hamani**</ins>, le <ins>**01 avril 2021**</ins> + +# Pré-requis + +Le programme a été réalisé sous Java 11. Pour lancer le programme, il va donc falloir cette version de JRE. Elle est trouvable sur [le site officiel d'Oracle](https://www.oracle.com/fr/java/technologies/javase-downloads.html) avec [leur documentation d'installation](https://docs.oracle.com/en/java/javase/11/install/installation-jdk-linux-platforms.html). + +Le projet a été construit à partir de Maven. Maven est installable via la ligne de commande `sudo apt install maven` sur Linux ou bien sur Windows en téléchargeant l'archive sur [le site officiel d'Apache](https://maven.apache.org/download.cgi) et en suivant [leur documentation d'installation](https://maven.apache.org/install.html). + +# Utilisation + +Avant de pouvoir lancer le programme, il faut le compiler avec `mvn package`. + +Le programme se lance ensuite en ligne de commande sans argument. + +Exemple d'utilisation : `mvn exec:java` + +Au lancement du programme, `un username et un password seront demandés` afin d'authentifier l'utilisateur. Si ceux-ci ne correspondent à aucun utilisateur autorisé à utiliser la plateforme, le programme le rejectera. + +Si les identifiants correspondent bien à un utilisateur autorisé à utiliser la plateforme, le programme lancera la plateforme à l'adresse `http://localhost:8080/myapp/`. + +Afin d'arrêter la plateforme, vous pouvez soit faire un `Ctrl+C` sur le terminal de lancement ou soit envoyer un signal `SIGKILL` au processus. Une solution permettant simplement d'écrire `stop` sur le terminal de lancement a été implémentée mais une exception au niveau du code généré lors de l'initialisation du projet, est levée empêchant cette solution de fonctionner. + +# Architecture + +Le projet a été construit à partir de Maven en utilisant la commande suivante : + +```sh +mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes -DarchetypeArtifactId=jersey-quickstart-grizzly2 -DarchetypeVersion=2.33 +``` + +L'archive du projet, après la compilation, est `target/flopbox-1.0-SNAPSHOT.jar`. + +Le code se situe dans le dossier `src/main/java/flopbox` depuis la racine du projet. + +Les tests se situent dans le dossier `src/test/java/flopbox` depuis la racine du projet. + +Le projet contient les packages suivants : + +- **account** -> Le package relatif aux comptes pouvant utiliser la plateforme +- **command** -> Le package relatif aux commandes utilisables par la plateforme +- **server** -> Le package relatif aux serveurs auxquels peut se connecter la plateforme + +# Commandes supportées + +La plateforme supporte les commandes curls suivantes : + +```curl +curl -v http://localhost:8080/myapp/myresource/cdup +curl -v http://localhost:8080/myapp/myresource/connect:{String address}:{int port} +curl -v http://localhost:8080/myapp/myresource/cwd:{String pathname} +curl -v http://localhost:8080/myapp/myresource/dele:{String pathname} +curl -v http://localhost:8080/myapp/myresource/list +curl -v http://localhost:8080/myapp/myresource/login:{String username}:{String password} +curl -v http://localhost:8080/myapp/myresource/mkd:{String pathname} +curl -v http://localhost:8080/myapp/myresource/pasv +curl -v http://localhost:8080/myapp/myresource/port +curl -v http://localhost:8080/myapp/myresource/pwd +curl -v http://localhost:8080/myapp/myresource/quit +curl -v http://localhost:8080/myapp/myresource/retr:{String pathname} +curl -v http://localhost:8080/myapp/myresource/rn:{String oldfilename}:{String newfilename} +curl -v http://localhost:8080/myapp/myresource/stor:{String pathname} +curl -v http://localhost:8080/myapp/myresource/type:{int type} +``` + +**Les informations entre crochets sont des variables à modifier dont le type a été indiqué pour plus de clarté.** + +Par exemple, pour se connecter au serveur ftp.ubuntu.com, la commande à utiliser est : + +```curl +curl -v http://localhost:8080/myapp/myresource/connect:ftp.ubuntu.com:21 +``` + +# Quelques exemples de code + +```java +/** + * Return if the password tried is the password of the account's username. + * + * @param username The username registered. + * @param password The password tried. + * + * @return If the password tried is the password of the username's account. + */ +public static boolean isTheRightPassword(String username, String password) +{ + if(accounts.containsKey(username)) + return password.equals(accounts.get(username)); + + else + return username.equals("anonymous"); +} +``` + +L'objet `accounts` est une `Map<String,String>` contenant les paires `<username,password>`. Cette fonction a un comportement similaire à celui des serveurs ftp. Elle vérifie tous les utilisateurs tentant de s'enregistrer auprès de la plateforme sauf `anonymous`. + +```java +/** + * Load the unique aliases in the program. + */ +public static void loadAliases() +{ + Map<String, String> aliases = Main.getAliases(); + + try + { + BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt)); + + String line; + while((line = reader.readLine()) != null) + { + int cut = line.indexOf(separator); + + String alias = line.substring(0, cut); + + /* If a same alias has already been put, we ignore it */ + if(aliases.containsKey(alias)) + continue; + + String server = line.substring(cut+1); + + aliases.put(alias, server); + } + + reader.close(); + } + + catch(IOException e) + { + /* Do nothing */ + } +} +``` + +Cette méthode `enregistre tous les alias uniques` des serveurs. Pour cela, elle va lire un fichier nommé `aliases.txt` à la racine du projet. `Pour ajouter ou modifier une association, c'est dans ce fichier que ça se passe.` Un système identique a été mis en place avec le fichier `accounts.txt` pour les `comptes autorisés à se connecter` à la plateforme. + +```java +/** + * List the files of the working directory. + * + * @param client The FTP client. + * + * @return How the command went. + */ +@GET +@Path("list") +@Produces(MediaType.TEXT_PLAIN) +public String list(FTPClient client) +{ + return LIST.execute(client); +} +``` + +La gestion des commandes se fait de cette façon. `Toutes les commandes sont récupérées avec @GET mais avec un @Path différent` afin de les différencier. + +```java +/** + * List the files of the working directory. + * + * @param client The FTP client. + * + * @return How the command went. + */ +public static String execute(FTPClient client) +{ + String response = ""; + + try + { + FTPFile[] files = client.listFiles(); + + for(FTPFile file : files) + { + response += file.getName() + "\n"; + } + } + + catch(IOException e) + { + response = "The command \"" + NAME + "\" failed."; + } + + return response; +} +``` + +`Le traitement des commandes est effectué dans des classes propres` aux commandes dans le package `command`. Ce, afin que le code soit plus clair et mieux structuré. + +# Les tests + +Aucun test n'a été réalisé cette fois-ci. + +Les efforts ont été concentrés à rendre la plateforme fonctionnel. + +# Ce que j'aurai amélioré avec le temps + +J'aurais `mieux designé la gestion de l'authentification` auprès de la plateforme. + +J'aurais `expérimenté le multi-threading` de la plateforme. + +J'aurais `débuggé les communications plateforme-serveur` (malgré que j'y ai passé déjà plusieurs jours). \ No newline at end of file diff --git a/pom.xml b/pom.xml index c34d5b7d34223949be23a2c368a27b89a79ff803..10796916cd1961448fcf78e8a05174a628275a89 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,20 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <groupId>flopbox</groupId> <artifactId>flopbox</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>flopbox</name> + + <dependencyManagement> <dependencies> <dependency> @@ -21,11 +27,14 @@ </dependencies> </dependencyManagement> + + <dependencies> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-grizzly2-http</artifactId> </dependency> + <dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> @@ -44,13 +53,6 @@ <scope>test</scope> </dependency> - <!-- https://mvnrepository.com/artifact/org.glassfish.grizzly/grizzly-http-server --> - <dependency> - <groupId>org.glassfish.grizzly</groupId> - <artifactId>grizzly-http-server</artifactId> - <version>3.0.0</version> - </dependency> - <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> <groupId>commons-net</groupId> @@ -59,6 +61,8 @@ </dependency> </dependencies> + + <build> <plugins> <plugin> @@ -71,6 +75,7 @@ <target>1.7</target> </configuration> </plugin> + <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> @@ -103,8 +108,10 @@ </plugins> </build> + + <properties> - <jersey.version>3.0.1</jersey.version> + <jersey.version>2.33</jersey.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project> diff --git a/scripts/delete.sh b/scripts/delete.sh new file mode 100755 index 0000000000000000000000000000000000000000..8a9e70ce3e21e17dad0ce290bb93b11adc78f74d --- /dev/null +++ b/scripts/delete.sh @@ -0,0 +1,31 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "------------------------------------" +echo "We can delete any directory we want." +echo "------------------------------------" + +echo "" +curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_delete' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous' +echo "" + +echo "------------------------------------" +echo "We can also delete any file we want." +echo "------------------------------------" + +echo "" +curl --request DELETE 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme01.jpg' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/scripts/download.sh b/scripts/download.sh new file mode 100755 index 0000000000000000000000000000000000000000..af9e8eb37c1af83a970f73130a9f36b088bde9d6 --- /dev/null +++ b/scripts/download.sh @@ -0,0 +1,23 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "---------------------------------" +echo "We can download any file we want." +echo "---------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html/download' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/scripts/list.sh b/scripts/list.sh new file mode 100755 index 0000000000000000000000000000000000000000..da774ebf379e0a01c6274b67dc92b1e3a806013c --- /dev/null +++ b/scripts/list.sh @@ -0,0 +1,31 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/ubuntu' --header 'host:ftp.ubuntu.com' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "----------------------------------" +echo "We can list any directory we want." +echo "----------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/ubuntu/' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous' +echo "" + +echo "----------------------------------" +echo "We can also list any file we want." +echo "----------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/ubuntu/cdimage/bionic/daily-live/20200805/FOOTER.html' --header 'port:21' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/scripts/makeDir.sh b/scripts/makeDir.sh new file mode 100755 index 0000000000000000000000000000000000000000..8bd31066c6e46d4a97103c0b873f71aa3cf59e91 --- /dev/null +++ b/scripts/makeDir.sh @@ -0,0 +1,23 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "------------------------------------" +echo "We can create any directory we want." +echo "------------------------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/localhost/testFiles/dir_created' --header 'port:2121' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/scripts/rename.sh b/scripts/rename.sh new file mode 100755 index 0000000000000000000000000000000000000000..895752d5f4b9c2671ff2e6c3e2b12b4423f590ac --- /dev/null +++ b/scripts/rename.sh @@ -0,0 +1,31 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "------------------------------------" +echo "We can create any directory we want." +echo "------------------------------------" + +echo "" +curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/dir_to_rename' --header 'port:2121' --header 'to:dir_renamed' --header 'username:anonymous' --header 'password:anonymous' +echo "" + +echo "------------------------------------" +echo "We can also rename any file we want." +echo "------------------------------------" + +echo "" +curl --request PATCH 'http://localhost:8080/flopbox/localhost/testFiles/Lysithea_meme02.png' --header 'port:2121' --header 'to:meme_renamed' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/scripts/upload.sh b/scripts/upload.sh new file mode 100755 index 0000000000000000000000000000000000000000..a11a1e39e0d0001ba40588665b2ce7e117ad672f --- /dev/null +++ b/scripts/upload.sh @@ -0,0 +1,23 @@ +echo "---------------------" +echo "We register a server." +echo "---------------------" + +echo "" +curl --request PUT 'http://localhost:8080/flopbox/localhost' --header 'host:localhost' +echo "" + +echo "-----------------------------------------" +echo "We check it is in the registered servers." +echo "-----------------------------------------" + +echo "" +curl --request GET 'http://localhost:8080/flopbox/' +echo "" + +echo "-------------------------------" +echo "We can upload any file we want." +echo "-------------------------------" + +echo "" +curl --request POST 'http://localhost:8080/flopbox/localhost/meme_uploaded/upload' --header 'port:2121' --header 'from:testFiles/Lysithea_meme03.png' --header 'username:anonymous' --header 'password:anonymous' +echo "" \ No newline at end of file diff --git a/src/main/java/flopbox/Main.java b/src/main/java/flopbox/Main.java index a1b4c4ebd8c4577d09f427a6cb2861c36a0b93eb..a904d8f0aaa0d20d0973bedb2a9e73a95d85c58c 100644 --- a/src/main/java/flopbox/Main.java +++ b/src/main/java/flopbox/Main.java @@ -1,82 +1,27 @@ package flopbox; - - -import flopbox.account.AccountUtil; - - -import org.apache.commons.net.ftp.FTPClient; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.server.ResourceConfig; import java.io.IOException; import java.net.URI; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; /** * Main class. - * */ public class Main { - /* URI the Grizzly HTTP server will listen on */ - private static String uri = "http://localhost:8080/myapp/"; - - /* Client the platform will use to connect to */ - private static FTPClient client = new FTPClient(); - - /* Aliases of the servers the platform recognizes */ - private static Map<String, String> aliases = new HashMap<String, String>(); - - /* Getters */ - public static String getUri() { return uri ; } - public static FTPClient getClient() { return client ; } - public static Map<String, String> getAliases() { return aliases ; } - - - - /** - * Tell the user how to use the program. - */ - public static void usage() - { - System.out.println("The program should be launched like that : java -jar target/flopbox-1.0-SNAPSHOT.jar [ftp server address] [ftp server port] [flopbox port] [username] [password]"); - } - - - - /** - * Log in the platform. - * - * @return if - */ - public static boolean login() - { - Scanner scanner = new Scanner(System.in); - - /* Set the username and password which will be used to log in the platform and the ftp server */ - System.out.print("Username : "); - String username = scanner.nextLine(); - System.out.print("Password : "); - String password = scanner.nextLine(); - - System.out.println(); - - scanner.close(); - - return AccountUtil.isTheRightPassword(username, password); - } - - - + // Base URI the Grizzly HTTP server will listen on + public static final String BASE_URI = "http://localhost:8080/flopbox/"; + + + /** * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application. - * + * * @return Grizzly HTTP server. */ public static HttpServer startServer() @@ -87,32 +32,11 @@ public class Main // create and start a new instance of grizzly http server // exposing the Jersey application at BASE_URI - return GrizzlyHttpServerFactory.createHttpServer(URI.create(uri), rc); - } - - - - /** - * Wait a word from the user. - */ - public static void waitWord() - { - Scanner scanner = new Scanner(System.in); - - String wordToGet = "stop"; - String wordGot; - - do - { - wordGot = scanner.nextLine().toLowerCase(); - } - while(!wordGot.equals(wordToGet)); - - scanner.close(); + return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc); } + - /** * Main method. * @@ -122,25 +46,13 @@ public class Main */ public static void main(String[] args) throws IOException { - /* Exit the program if the username is unknown or the password is wrong */ - AccountUtil.loadAccounts(); - if(!login()) - { - System.out.println("Unknown account."); - usage(); - System.exit(1); - } - - /* Start the server */ final HttpServer server = startServer(); + System.out.println(String.format("Jersey app started with WADL available at " - + "%sapplication.wadl\nHit enter to stop it...", uri)); + + "%sapplication.wadl\nHit enter to stop it...", BASE_URI)); System.in.read(); - /* Wait a word from the user to then shutdown the server */ - // waitWord(); - server.shutdownNow(); } } diff --git a/src/main/java/flopbox/MyResource.java b/src/main/java/flopbox/MyResource.java index 06d77288c09b1b4688e8bf54270b4a7ce711946b..6e66ac58b487856096fc665344b2cbdd779b6c8f 100644 --- a/src/main/java/flopbox/MyResource.java +++ b/src/main/java/flopbox/MyResource.java @@ -1,295 +1,287 @@ package flopbox; - - +import flopbox.client.ClientUtil; import flopbox.command.*; -import java.net.ServerSocket; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PATCH; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import org.apache.commons.net.ftp.FTPClient; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; - /** - * Root resource (exposed at "myresource" path) + * Root resource (exposed at "/" path) */ -@Path("myresource") +@Path("/") public class MyResource { - private FTPClient client = Main.getClient(); - private ServerSocket activeConnection; - - - /** - * Change to the parent directory. - * - * @param client The FTP client. + * Print the registered servers and their hosts. * - * @return How the command went. + * @return the registered servers and their hosts. */ - @GET - @Path("cdup") + @GET @Produces(MediaType.TEXT_PLAIN) - public String cdup(FTPClient client) + public String printServers() { - return CDUP.execute(client); + return ServerCommands.print(); } - - - - /** - * Connect the client to a ftp server. + + /** + * Register a server and its host in the platform. * - * @param client The FTP client. - * @param address The address of the ftp server. - * @param port The port of the ftp server. + * @param server The server. + * @param host The host of the server. * * @return How the command went. */ - @GET - @Path("connect:{address}:{port}") + @PUT + @Path("{server}") @Produces(MediaType.TEXT_PLAIN) - public String connect(FTPClient client, @PathParam("address") String address, @PathParam("port") int port) + public String registerServer(@PathParam("server") String server, @HeaderParam("host") String host) { - return CONNECT.execute(client, address, port); + return ServerCommands.register(server, host) + "\n"; } - - /** - * Change the working directory. + * Delete a registered server of the platform. * - * @param client The FTP client. - * @param pathname The pathname of the next working directory. + * @param server The server. * * @return How the command went. */ - @GET - @Path("cwd:{pathname}") + @DELETE + @Path("{server}") @Produces(MediaType.TEXT_PLAIN) - public String cwd(FTPClient client, @PathParam("pathname") String pathname) + public String deleteServer(@PathParam("server") String server) { - return CWD.execute(client, pathname); + return ServerCommands.delete(server) + "\n"; } - - /** - * Delete a file. + * Modify the host of a server of the platform. * - * @param client The FTP client. - * @param pathname The pathname of a file. + * @param server The server. + * @param host The new host of the server. * * @return How the command went. */ - @GET - @Path("dele:{pathname}") + @PATCH + @Path("{server}") @Produces(MediaType.TEXT_PLAIN) - public String dele(FTPClient client, @PathParam("pathname") String pathname) + public String modifyServer(@PathParam("server") String server, @HeaderParam("host") String host) { - return DELE.execute(client, pathname); + return ServerCommands.modify(server, host) + "\n"; } - + /** - * List the files of the working directory. - * - * @param client The FTP client. - * - * @return How the command went. - */ - @GET - @Path("list") + * Create a directory on the FTP server. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param path The path of the file directory to create. + * + * @return How the command went. + */ + @PUT + @Path("{server}/{path:.*}") @Produces(MediaType.TEXT_PLAIN) - public String list(FTPClient client) + public String makeDir(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username, @HeaderParam("password") String password, + @PathParam ("path" ) String path ) { - return LIST.execute(client); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.makeDir(client, path); + ClientUtil.logoutAndDisconnect(client); + } + else + return "The connection to the server failed."; + + return response + "\n"; } - - - - /** - * Login with a username and a password. - * - * @param client The FTP client. - * @param username The username. - * @param password The password. - * - * @return How the command went. - */ - @GET - @Path("login:{username}:{password}") - @Produces(MediaType.TEXT_PLAIN) - public String login(FTPClient client, @PathParam("username") String username, @PathParam("password") String password) - { - return LOGIN.execute(client, username, password); - } - - /** - * Make a new directory. - * - * @param client The FTP client. - * @param pathname The pathname of the new directory. - * - * @return How the command went. - */ - @GET - @Path("mkd:{pathname}") + * Delete a file or directory on the FTP server. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param path The path of the file or directory to delete. + * + * @return How the command went. + */ + @DELETE + @Path("{server}/{path:.*}") @Produces(MediaType.TEXT_PLAIN) - public String mkd(FTPClient client, @PathParam("pathname") String pathname) + public String delete(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username, @HeaderParam("password") String password, + @PathParam ("path" ) String path ) { - return MKD.execute(client, pathname); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.delete(client, path); + ClientUtil.logoutAndDisconnect(client); + } + else + return "The connection to the server failed."; + + return response + "\n"; } - - - - /** - * Enter in passive mode. - * - * @param client The FTP client. - * - * @return How the command went. - */ - @GET - @Path("pasv") - @Produces(MediaType.TEXT_PLAIN) - public String pasv(FTPClient client) + + /** + * Download a file. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param path The path of the file to download. + * + * @return How the command went. + */ + @GET + @Path("{server}/{path:.*}/download") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN}) + public String download(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username , @HeaderParam("password") String password, + @PathParam ("path" ) String path ) { - return PASV.execute(client); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.download(client, path); + ClientUtil.logoutAndDisconnect(client); + } + else + response = "The connection to the server failed."; + + return response + "\n"; } - - - - /** - * Enter in active mode. - * - * @param client The FTP client. - * @param activeConnection The active connection. - * - * @return How the command went. - */ - @GET - @Path("port") + + /** + * List information about a file or files in a directory on the FTP server. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param path The path of the file or directory. + * + * @return Information about the file or files in the directory. + */ + @GET + @Path("{server}/{path:.*}") @Produces(MediaType.TEXT_PLAIN) - public String port(FTPClient client) + public String list(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username, @HeaderParam("password") String password, + @PathParam ("path" ) String path ) { - return PORT.execute(client, activeConnection); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.list(client, path); + ClientUtil.logoutAndDisconnect(client); + } + else + response = "The connection to the server failed."; + + return response; } - - /** - * Print the working directory. - * - * @param client The FTP client. - * - * @return How the command went. - */ - @GET - @Path("pwd") + * Rename a file or directory on the FTP server. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param from The path of the file or directory to rename. + * @param to The new name of the file or directory. + * + * @return How the command went. + */ + @PATCH + @Path("{server}/{from}") @Produces(MediaType.TEXT_PLAIN) - public String pwd(FTPClient client) + public String rename(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username, @HeaderParam("password") String password, + @PathParam ("from" ) String from , @HeaderParam("to" ) String to ) { - return PWD.execute(client); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.rename(client, from, to); + ClientUtil.logoutAndDisconnect(client); + } + else + response = "The connection to the server failed."; + + return response + "\n"; } - - - - /** - * Disconnect from the server. - * - * @param client The FTP client. - * - * @return How the command went. - */ - @GET - @Path("quit") - @Produces(MediaType.TEXT_PLAIN) - public String quit() - { - return QUIT.execute(client); - } - - - - /** - * Retrieve a file. - * - * @param client The FTP client. - * @param pathname The pathname of the file to retrieve. - * - * @return How the command went. - */ - @GET - @Path("retr:{pathname}") - @Produces(MediaType.TEXT_PLAIN) - public String retr(FTPClient client, @PathParam("pathname") String pathname) - { - return RETR.execute(client, pathname); - } - - - - /** - * Rename a file. - * - * @param client The FTP client. - * @param oldFilename The old filename. - * @param newFilename The new filename. - * - * @return How the command went. - */ - @GET - @Path("rn:{oldFilename}:{newFilename}") - @Produces(MediaType.TEXT_PLAIN) - public String rn(FTPClient client, @PathParam("oldFilename") String oldFilename, @PathParam("newFilename") String newFilename) + + /** + * Store a file or directory on the FTP server. + * + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * @param from The input stream of the file or directory to upload. + * @param to The path where to store the input stream. + * + * @return How the command went. + */ + @POST + @Path("{server}/{to:.*}/upload") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN}) + public String upload(@PathParam ("server" ) String server , @HeaderParam("port" ) int port , + @HeaderParam("username") String username , @HeaderParam("password") String password, + @HeaderParam("from" ) String from , @PathParam ("to" ) String to ) { - return RN.execute(client, oldFilename, newFilename); + FTPClient client = new FTPClient(); + + String response; + + if(ClientUtil.connectAndLogin(client, server, port, username, password)) + { + response = FtpCommands.upload(client, from, to); + ClientUtil.logoutAndDisconnect(client); + } + else + response = "The connection to the server failed."; + + return response + "\n"; } - - - - /** - * Store a file. - * - * @param client The FTP client. - * @param pathname The pathname of the file to store. - * - * @return How the command went. - */ - @GET - @Path("stor:{pathname}") - @Produces(MediaType.TEXT_PLAIN) - public String stor(FTPClient client, @PathParam("pathname") String pathname) - { - return STOR.execute(client, pathname); - } - - - - /** - * Set the type. - * - * @param client The FTP client. - * @param type The position of the desired type in the string of types. - * - * @return How the command went. - */ - @GET - @Path("type:{type}") - @Produces(MediaType.TEXT_PLAIN) - public String type(FTPClient client, @PathParam("type") int type) - { - return TYPE.execute(client, type); - } } diff --git a/src/main/java/flopbox/account/AccountUtil.java b/src/main/java/flopbox/account/AccountUtil.java deleted file mode 100644 index ab1633fa5413789669c2bfc994feb3d67592c8cd..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/account/AccountUtil.java +++ /dev/null @@ -1,87 +0,0 @@ -package flopbox.account; - - - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - - - -public class AccountUtil -{ - private static File accountsTxt = new File("accounts.txt"); - private static char separator = ' '; - - private static Map<String, String> accounts = new HashMap<String, String>(); - - - - /** - * Let the other classes to access in read the registered accounts. - * - * @return The pair username and password of the accounts. - */ - public static Map<String, String> getAccounts() - { - return accounts; - } - - - - /** - * Load the unique usernames in the program. - */ - public static void loadAccounts() - { - try - { - BufferedReader reader = new BufferedReader(new FileReader(accountsTxt)); - - String line; - while((line = reader.readLine()) != null) - { - int cut = line.indexOf(separator); - - String username = line.substring(0, cut); - - /* If a same username has already been put, we ignore it */ - if(accounts.containsKey(username)) - continue; - - String password = line.substring(cut+1); - - accounts.put(username, password); - } - - reader.close(); - } - - catch(IOException e) - { - /* Do nothing */ - } - } - - - - /** - * Return if the password tried is the password of the account's username. - * - * @param username The username registered. - * @param password The password tried. - * - * @return If the password tried is the password of the username's account. - */ - public static boolean isTheRightPassword(String username, String password) - { - if(accounts.containsKey(username)) - return password.equals(accounts.get(username)); - - else - return username.equals("anonymous"); - } -} \ No newline at end of file diff --git a/src/main/java/flopbox/client/ClientUtil.java b/src/main/java/flopbox/client/ClientUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..29f4795e09c0a1ec2663613eb0e033d2ca382583 --- /dev/null +++ b/src/main/java/flopbox/client/ClientUtil.java @@ -0,0 +1,69 @@ +package flopbox.client; + +import java.io.IOException; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPReply; + +import flopbox.command.ServerCommands; + + + +public class ClientUtil +{ + /** + * Connect and log in the FTP server. + * + * @param client The FTP client. + * @param server The FTP server to connect to. + * @param port The port of the FTP server to connect to. + * @param username The username of the account to use. + * @param password The password of the account to use. + * + * @return True if the client could connect and log in the FTP server, otherwise false. + */ + public static boolean connectAndLogin(FTPClient client, String server, int port, String username, String password) + { + try + { + client.connect(ServerCommands.getServers().get(server), port); + + if(FTPReply.isPositiveCompletion(client.getReplyCode())) + if(client.login(username, password)) + return client.setFileType(FTPClient.BINARY_FILE_TYPE); + + return false; + } + + catch(IOException e) + { + return false; + } + } + + + /** + * Log out and disconnect from the FTP server. + * + * @param client The FTP client. + * + * @return True if the client could log out and disconnect from the FTP server. + */ + public static boolean logoutAndDisconnect(FTPClient client) + { + try + { + if(!client.logout()) + return false; + + client.disconnect(); + + return true; + } + + catch(IOException e) + { + return false; + } + } +} diff --git a/src/main/java/flopbox/command/CDUP.java b/src/main/java/flopbox/command/CDUP.java deleted file mode 100644 index 828fd0f6dd5ff7223ec485cd72dd09c2d8fe016b..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/CDUP.java +++ /dev/null @@ -1,42 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class CDUP -{ - private static final String NAME = "CDUP"; - - - - /** - * Change to the parent directory. - * - * @param client The FTP client. - * - * @return How the command went. - */ - public static String execute(FTPClient client) - { - String response; - - try - { - if(client.changeToParentDirectory()) - response = "The working directory is now the parent directory."; - - else - response = "The working directory could not be changed."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/CONNECT.java b/src/main/java/flopbox/command/CONNECT.java deleted file mode 100644 index fd10f34e530fe47431d89333528ded2bc78770c9..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/CONNECT.java +++ /dev/null @@ -1,60 +0,0 @@ -package flopbox.command; - -import java.io.IOException; -import java.net.UnknownHostException; - -import org.apache.commons.net.ftp.FTPClient; - -import flopbox.Main; -import flopbox.server.FtpServerUtil; - -public class CONNECT -{ - private static final String NAME = "CONNECT"; - - - - /** - * Connect the client to a ftp server. - * - * @param client The FTP client. - * @param address The address of the ftp server. - * @param port The port of the ftp server. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String address, int port) - { - String response; - - try - { - if(client.isConnected()) - client.disconnect(); - - if(!FtpServerUtil.isAddressValid(address)) - if(Main.getAliases().containsKey(address)) - address = Main.getAliases().get(address); - - if(!FtpServerUtil.isFtpServerPortValid(port)) - response = "The port is wrong."; - else - { - client.connect(address, port); - response = "Connected."; - } - } - - catch(UnknownHostException e) - { - response = "The address could not be resolved."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/CWD.java b/src/main/java/flopbox/command/CWD.java deleted file mode 100644 index 80bc022591d2c43705b4c1f722f6d61f7eeb45f4..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/CWD.java +++ /dev/null @@ -1,43 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class CWD -{ - private static final String NAME = "CWD"; - - - - /** - * Change the working directory. - * - * @param client The FTP client. - * @param pathname The pathname of the next working directory. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String pathname) - { - String response; - - try - { - if(client.changeWorkingDirectory(pathname)) - response = "The working directory is : " + pathname; - - else - response = "The working directory could not be changed."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/DELE.java b/src/main/java/flopbox/command/DELE.java deleted file mode 100644 index 82f6f9b3dcbec3bcb483d359abf720b481c70d9c..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/DELE.java +++ /dev/null @@ -1,43 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class DELE -{ - private static final String NAME = "DELE"; - - - - /** - * Delete a file. - * - * @param client The FTP client. - * @param pathname The pathname of a file. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String pathname) - { - String response; - - try - { - if(client.deleteFile(pathname)) - response = "The file \"" + pathname + "\" has been deleted."; - - else - response = "The file \"" + pathname + "\" could not be deleted."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/FtpCommands.java b/src/main/java/flopbox/command/FtpCommands.java new file mode 100644 index 0000000000000000000000000000000000000000..1905a6b2e105b3b04a4efcb854c308aa98a72216 --- /dev/null +++ b/src/main/java/flopbox/command/FtpCommands.java @@ -0,0 +1,233 @@ +package flopbox.command; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; + + + +public class FtpCommands +{ + /** + * Create a directory on the FTP server. + * + * @param client The FTP client. + * @param path The path of the directory to create. + * + * @return How the command went. + */ + public static String makeDir(FTPClient client, String path) + { + String response; + + try + { + if(client.makeDirectory(path)) + response = "The directory \"" + path + "\" has been created."; + else + response = "The directory \"" + path + "\" could not be created."; + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } + + + + /** + * Delete a file or directory on the FTP server. + * + * @param client The FTP client. + * @param path The path of the file or directory to delete. + * + * @return How the command went. + */ + public static String delete(FTPClient client, String path) + { + String response; + + try + { + if(client.deleteFile(path) || client.removeDirectory(path)) + response = "\"" + path + "\" has been deleted."; + else + response = "\"" + path + "\" could not be deleted or does not exist."; + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } + + + + /** + * Download a file. + * + * @param client The FTP client. + * @param path The path of the file to download + * + * @return How the command went. + */ + public static String download(FTPClient client, String path) + { + String response; + + try + { + client.enterLocalPassiveMode(); + + /* We take the filename and working directory from the full path */ + String workingDirectory = path.substring(0, path.lastIndexOf("/")); + String filename = path.substring( path.lastIndexOf("/")+1); + + /* We create the file and its data */ + File file = new File("downloads/" + filename); + while(file.exists()) + { + String name = filename.substring(0, filename.lastIndexOf(".")); + String extension = filename.substring( filename.lastIndexOf(".")); + file = new File("downloads/" + name + "_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + extension); + } + OutputStream fileOutputStream = new FileOutputStream(file); + + /* We move to the working directory and retrieve the file */ + if(client.changeWorkingDirectory(workingDirectory) && client.retrieveFile(filename, fileOutputStream)) + response = "The download is a success."; + else + { + file.delete(); + response = "The download failed."; + } + + fileOutputStream.close(); + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } + + + + /** + * List information about a file or files in a directory on the FTP server. + * + * @param client The FTP client. + * @param path The path of the file or directory. + * + * @return Information about the file or files in the directory. + */ + public static String list(FTPClient client, String path) + { + String response = ""; + + try + { + client.enterLocalPassiveMode(); + + FTPFile[] files = client.listFiles(path); + + for(FTPFile file : files) + { + response += file.getRawListing(); + response += "\n"; + } + + return response; + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } + + + + /** + * Rename a file or directory on the FTP server. + * + * @param client The FTP client. + * @param from The path of the file or directory to rename. + * @param to The new name of the file or directory. + * + * @return How the command went. + */ + public static String rename(FTPClient client, String from, String to) + { + String response; + + try + { + if(client.rename(from, to)) + response = "\"" + from + "\" has been renamed to \"" + to + "\"."; + else + response = "\"" + from + "\" could not be renamed."; + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } + + + + /** + * Store a file or directory on the FTP server. + * + * @param client The FTP client. + * @param from The input stream of the file or directory to upload. + * @param to The path where to store the input stream. + * + * @return How the command went. + */ + public static String upload(FTPClient client, String from, String to) + { + String response; + + try + { + InputStream fileInputStream = new FileInputStream(new File(from)); + + client.enterLocalPassiveMode(); + + if(client.storeFile(to, fileInputStream)) + response = "The upload is a success."; + else + response = "The upload failed."; + + fileInputStream.close(); + } + + catch(IOException e) + { + response = "An IO error occured while sending the command or receiving its result."; + } + + return response; + } +} diff --git a/src/main/java/flopbox/command/LIST.java b/src/main/java/flopbox/command/LIST.java deleted file mode 100644 index 38989be28c55e31d961eea7dd67b589daf94f2e6..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/LIST.java +++ /dev/null @@ -1,44 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPFile; - - - -public class LIST -{ - private static final String NAME = "LIST"; - - - - /** - * List the files of the working directory. - * - * @param client The FTP client. - * - * @return How the command went. - */ - public static String execute(FTPClient client) - { - String response = ""; - - try - { - FTPFile[] files = client.listFiles(); - - for(FTPFile file : files) - { - response += file.getName() + "\n"; - } - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/LOGIN.java b/src/main/java/flopbox/command/LOGIN.java deleted file mode 100644 index 19ec2c2148a57cc2a495d99a102a550d880358b2..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/LOGIN.java +++ /dev/null @@ -1,48 +0,0 @@ -package flopbox.command; - - - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class LOGIN -{ - private static final String NAME = "LOGIN"; - - - - /** - * Login with a username and a password. - * - * @param client The FTP client. - * @param username The username. - * @param password The password. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String username, String password) - { - String response; - - try - { - if(client.login(username, password)) - { - response = "The login has succeed."; - } - - else - response = "The login has not succeed."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/MKD.java b/src/main/java/flopbox/command/MKD.java deleted file mode 100644 index c49643df2c98a4e74be297266b4871a0a3a54fb3..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/MKD.java +++ /dev/null @@ -1,43 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class MKD -{ - private static final String NAME = "MKD"; - - - - /** - * Make a new directory. - * - * @param client The FTP client. - * @param pathname The pathname of the new directory. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String pathname) - { - String response; - - try - { - if(client.makeDirectory(pathname)) - response = "The directory \"" + pathname + "\" has been created."; - - else - response = "The directory \"" + pathname + "\" could not be created."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/PASV.java b/src/main/java/flopbox/command/PASV.java deleted file mode 100644 index 54f96e8eb03d77ecac9a35595334585ca6b60337..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/PASV.java +++ /dev/null @@ -1,33 +0,0 @@ -package flopbox.command; - - - -import org.apache.commons.net.ftp.FTPClient; - - - -public class PASV -{ - /** - * Enter in passive mode. - * - * @param client The FTP client. - * - * @return How the command went. - */ - public static String execute(FTPClient client) - { - String response; - - if(client.isConnected()) - { - client.enterLocalPassiveMode(); - response = "The client entered in passive mode."; - } - - else - response = "The client could not enter in passive mode."; - - return response; - } -} diff --git a/src/main/java/flopbox/command/PORT.java b/src/main/java/flopbox/command/PORT.java deleted file mode 100644 index 404abb781a9513d4aced5e9271c9156a5c745314..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/PORT.java +++ /dev/null @@ -1,57 +0,0 @@ -package flopbox.command; - - - -import java.io.IOException; -import java.net.ServerSocket; - -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; - - - -public class PORT -{ - private static final String NAME = "PORT"; - - - - /** - * Enter in active mode. - * - * @param client The FTP client. - * @param activeConnection The active connection. - * - * @return How the command went. - */ - public static String execute(FTPClient client, ServerSocket activeConnection) - { - String response; - - try - { - if(client.isConnected()) - { - activeConnection = new ServerSocket(0); - - int commandResponse = client.port(client.getRemoteAddress(), activeConnection.getLocalPort()); - - if(FTPReply.isPositiveCompletion(commandResponse)) - response = "The client entered in active mode."; - - else - response = "The client could not enter in active mode."; - } - - else - response = "The client could not enter in active mode."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/PWD.java b/src/main/java/flopbox/command/PWD.java deleted file mode 100644 index 83a230a156fcdc129b9a91d85970978f4a64ddcd..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/PWD.java +++ /dev/null @@ -1,44 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class PWD -{ - private static final String NAME = "PWD"; - - - - /** - * Print the working directory. - * - * @param client The FTP client. - * - * @return How the command went. - */ - public static String execute(FTPClient client) - { - String response; - - try - { - response = client.printWorkingDirectory(); - - if(response != null) - response = "The working directory is : " + response; - - else - response = "The working directory could not be printed."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/QUIT.java b/src/main/java/flopbox/command/QUIT.java deleted file mode 100644 index 90cb9143cd42e675f402266f4571b855bb1aaf5b..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/QUIT.java +++ /dev/null @@ -1,47 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; - - - -public class QUIT -{ - private static final String NAME = "QUIT"; - - - - /** - * Disconnect from the server. - * - * @param client The FTP client. - * - * @return How the command went. - */ - public static String execute(FTPClient client) - { - String response; - - try - { - int commandResponse = client.quit(); - - if(FTPReply.isPositiveCompletion(commandResponse)) - response = "Quit has succeed."; - - else - response = "Quit has not succeed."; - - //client.disconnect(); in case the connection is kept alive by the client. - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/RETR.java b/src/main/java/flopbox/command/RETR.java deleted file mode 100644 index 04c1f74cd8a43f1c5113f195c27260c36419bf32..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/RETR.java +++ /dev/null @@ -1,48 +0,0 @@ -package flopbox.command; - - - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; - - - -public class RETR -{ - private static final String NAME = "RETR"; - - - - /** - * Retrieve a file. - * - * @param client The FTP client. - * @param pathname The pathname of the file to retrieve. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String pathname) - { - String response; - - try - { - int commandResponse = client.retr(pathname); /* should either place the file in /tmp or in the root of the project */ - - if(FTPReply.isPositiveCompletion(commandResponse)) - response = "The file has been retrieved."; - - else - response = "The file could not be retrieved."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/RN.java b/src/main/java/flopbox/command/RN.java deleted file mode 100644 index 5735ebda163c0f8c150db1069e2ed941d64c534d..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/RN.java +++ /dev/null @@ -1,44 +0,0 @@ -package flopbox.command; - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class RN -{ - private static final String NAME = "RN"; - - - - /** - * Rename a file. - * - * @param client The FTP client. - * @param oldFilename The old filename. - * @param newFilename The new filename. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String oldFilename, String newFilename) - { - String response; - - try - { - if(client.rename(oldFilename, newFilename)) - response = "The file \"" + oldFilename + "\" has been renamed to \"" + newFilename + "\"."; - - else - response = "The file \"" + oldFilename + "\" could not be renamed."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/STOR.java b/src/main/java/flopbox/command/STOR.java deleted file mode 100644 index 77e287328c98d9dbe2fdc15062e2dc6d3493c9fa..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/STOR.java +++ /dev/null @@ -1,48 +0,0 @@ -package flopbox.command; - - - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; - - - -public class STOR -{ - private static final String NAME = "STOR"; - - - - /** - * Store a file. - * - * @param client The FTP client. - * @param pathname The pathname of the file to store. - * - * @return How the command went. - */ - public static String execute(FTPClient client, String pathname) - { - String response; - - try - { - int commandResponse = client.stor(pathname); - - if(FTPReply.isPositiveCompletion(commandResponse)) - response = "The file has been stored."; - - else - response = "The file could not be stored."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/command/ServerCommands.java b/src/main/java/flopbox/command/ServerCommands.java new file mode 100644 index 0000000000000000000000000000000000000000..8b6efcc7fd8384bbe4dcf738214da0325e81584a --- /dev/null +++ b/src/main/java/flopbox/command/ServerCommands.java @@ -0,0 +1,90 @@ +package flopbox.command; + +import java.util.HashMap; +import java.util.Map; + + + +public class ServerCommands +{ + /* Attributes */ + private static Map<String,String> servers = new HashMap<String,String>(); + + /* Getters */ + public static Map<String,String> getServers() { return servers; } + + + + /** + * Print the registered servers and their hosts. + * + * @return the registered servers and their hosts. + */ + public static String print() + { + String associations = ""; + + for(String server : servers.keySet()) + { + associations += server + " -> " + servers.get(server); + associations += "\n"; + } + + return associations; + } + + + + /** + * Register a server and its host in the platform. + * + * @param server The server. + * @param host The host of the server. + * + * @return How the command went. + */ + public static String register(String server, String host) + { + if(servers.containsKey(server)) + return "The server \"" + server + "\" is already registered."; + + servers.put(server, host); + + return "The association \"" + server + " -> " + host + "\" has been registered."; + } + + + + /** + * Delete a registered server of the platform. + * + * @param server The server. + * + * @return How the command went. + */ + public static String delete(String server) + { + if(servers.remove(server) == null) + return "The server \"" + server + "\" is not registered."; + else + return "The server \"" + server + "\" has been deleted."; + } + + + + /** + * Modify the host of a server of the platform. + * + * @param server The server. + * @param host The new host of the server. + * + * @return How the command went. + */ + public static String modify(String server, String host) + { + if(servers.replace(server, host) == null) + return "The server \"" + server + "\" is not registered."; + else + return "The server \"" + server + "\" is now associated with the host \"" + host + "\"."; + } +} diff --git a/src/main/java/flopbox/command/TYPE.java b/src/main/java/flopbox/command/TYPE.java deleted file mode 100644 index edb9c7601b7a7d763c64847e0ad80ff1ee677096..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/command/TYPE.java +++ /dev/null @@ -1,45 +0,0 @@ -package flopbox.command; - - - -import java.io.IOException; - -import org.apache.commons.net.ftp.FTPClient; - - - -public class TYPE -{ - private static final String NAME = "TYPE"; - - - - /** - * Set the type. - * - * @param client The FTP client. - * @param type The position of the desired type in the string of types. - * - * @return How the command went. - */ - public static String execute(FTPClient client, int type) - { - String response; - - try - { - if(client.setFileType(type)) - response = "The type has been set."; - - else - response = "The type could not be set."; - } - - catch(IOException e) - { - response = "The command \"" + NAME + "\" failed."; - } - - return response; - } -} diff --git a/src/main/java/flopbox/server/AliasUtil.java b/src/main/java/flopbox/server/AliasUtil.java deleted file mode 100644 index a2e234225095f446d6b3b9285f33092f71ce9b14..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/server/AliasUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -package flopbox.server; - - - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.Map; - -import flopbox.Main; - - - -public class AliasUtil -{ - private static File aliasesTxt = new File("aliases.txt"); - private static char separator = ' '; - - - - /** - * Load the unique aliases in the program. - */ - public static void loadAliases() - { - Map<String, String> aliases = Main.getAliases(); - - try - { - BufferedReader reader = new BufferedReader(new FileReader(aliasesTxt)); - - String line; - while((line = reader.readLine()) != null) - { - int cut = line.indexOf(separator); - - String alias = line.substring(0, cut); - - /* If a same alias has already been put, we ignore it */ - if(aliases.containsKey(alias)) - continue; - - String server = line.substring(cut+1); - - aliases.put(alias, server); - } - - reader.close(); - } - - catch(IOException e) - { - /* Do nothing */ - } - } -} diff --git a/src/main/java/flopbox/server/FtpServerUtil.java b/src/main/java/flopbox/server/FtpServerUtil.java deleted file mode 100644 index 897a7aa4b98e48ad205f1a5962563e792b65e8a2..0000000000000000000000000000000000000000 --- a/src/main/java/flopbox/server/FtpServerUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -package flopbox.server; - - - -import java.net.InetAddress; -import java.net.UnknownHostException; - - - -public class FtpServerUtil -{ - /** - * Tell if an address is resolvable. - * - * @param ftpServer The address. - * - * @return If an address is resolvable. - */ - public static boolean isAddressValid(String ftpServer) - { - try - { - InetAddress.getByName(ftpServer); - } - - catch(UnknownHostException e) - { - return false; - } - - return true; - - } - - - - /** - * Tell if a port is between 1 and 65535. - * - * @param port The port. - * - * @return If the port is between 1 and 65535. - */ - public static boolean isFtpServerPortValid(int port) - { - if(Math.pow(2, 0) > port || port >= Math.pow(2, 16)) - return false; - - return true; - } -} diff --git a/src/test/java/flopbox/MyResourceTest.java b/src/test/java/flopbox/MyResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7f31f9fb92c03cbba575f2e26f9f5ab8b95a5124 --- /dev/null +++ b/src/test/java/flopbox/MyResourceTest.java @@ -0,0 +1,48 @@ +//package flopbox; +// +//import javax.ws.rs.client.Client; +//import javax.ws.rs.client.ClientBuilder; +//import javax.ws.rs.client.WebTarget; +// +//import org.glassfish.grizzly.http.server.HttpServer; +// +//import org.junit.After; +//import org.junit.Before; +//import org.junit.Test; +//import static org.junit.Assert.assertEquals; +// +//public class MyResourceTest { +// +// private HttpServer server; +// private WebTarget target; +// +// @Before +// public void setUp() throws Exception { +// // start the server +// server = Main.startServer(); +// // create the client +// Client c = ClientBuilder.newClient(); +// +// // uncomment the following line if you want to enable +// // support for JSON in the client (you also have to uncomment +// // dependency on jersey-media-json module in pom.xml and Main.startServer()) +// // -- +// // c.configuration().enable(new org.glassfish.jersey.media.json.JsonJaxbFeature()); +// +// target = c.target(Main.BASE_URI); +// } +// +// @After +// public void tearDown() throws Exception { +// server.shutdownNow(); +// } +// +// /** +// * Test to see that the message "Got it!" is sent in the response. +// */ +//// @Test +//// public void testGetIt() { +//// String responseMsg = target.path("myresource").request().get(String.class); +//// assertEquals("Got it!", responseMsg); +//// } +//} diff --git a/testFiles/Explication_de_Lysithea_meme.txt b/testFiles/Explication_de_Lysithea_meme.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a641d2578a81f3a5c5774beb5e5b606664e9313 --- /dev/null +++ b/testFiles/Explication_de_Lysithea_meme.txt @@ -0,0 +1,25 @@ +Pour faire court, Lysithea est : + +- Le personnage le plus jeune de FE3H +- Le mage le plus puissant du jeu +- Le personnage qui évolue le plus vite du jeu + +Y'a un meme avec elle... +Death Knight est un ennemi infâme super tanky et qui fait super mal +L'attaquer c'est garantir la mort à son unité pour au final lui faire que du -5 sur 50pv + +Sauf que... +Il existe une magie super efficace contre lui + +Et... +Lysithea peut la débloquer +Elle y a accès rapidement puisqu'elle évolue plus rapidement que les autres +Elle gagne des stats plus rapidement et exactement là où il faut pour augmenter ses dégâts +A tel point qu'au final elle peut le one-shot avec n'importe quel autre sort :x + +Du coup... +Dès que Death Knight apparait sur le champ de bataille, on fait pop Lysi juste pour se débarasser de lui x) + + + +NB : Sérieusement, elle cogne vraiment fort \ No newline at end of file diff --git a/testFiles/Lysithea_meme01.jpg b/testFiles/Lysithea_meme01.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e62425c4c478ace0b978d93dd51d65e0767787bf Binary files /dev/null and b/testFiles/Lysithea_meme01.jpg differ diff --git a/testFiles/Lysithea_meme02.png b/testFiles/Lysithea_meme02.png new file mode 100644 index 0000000000000000000000000000000000000000..2133aa100b93e18c3598a34de429b81d3ba62576 Binary files /dev/null and b/testFiles/Lysithea_meme02.png differ diff --git a/testFiles/Lysithea_meme03.png b/testFiles/Lysithea_meme03.png new file mode 100644 index 0000000000000000000000000000000000000000..20bb707edf6d2555d82608dd0fbd80fdfaaa73f5 Binary files /dev/null and b/testFiles/Lysithea_meme03.png differ