Skip to content
Snippets Groups Projects
Commit 45a546f3 authored by ='s avatar =
Browse files

Rendu définitif

parent 6b5065ba
No related branches found
No related tags found
No related merge requests found
Showing
with 907 additions and 697 deletions
...@@ -12,22 +12,99 @@ Le projet a été construit à partir de Maven. Maven est installable via la lig ...@@ -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`. 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'
```
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}'
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`.
Si les identifiants correspondent bien à un utilisateur autorisé à utiliser la plateforme, le programme lancera la plateforme à l'adresse `http://localhost:8080/myapp/`. ```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'
```
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. 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 # Architecture
Le projet a été construit à partir de Maven en utilisant la commande suivante : Le projet a été construit à partir de Maven en utilisant la commande suivante :
```sh ```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`. 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 ...@@ -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 : 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 - **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 # Quelques exemples de code
```java ```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 server The server.
* @param password The password tried. * @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)) if(servers.containsKey(server))
return password.equals(accounts.get(username)); return "The server \"" + server + "\" is already registered.";
else servers.put(server, host);
return username.equals("anonymous");
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 ```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 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(FTPReply.isPositiveCompletion(client.getReplyCode()))
if(client.login(username, password))
return client.setFileType(FTPClient.BINARY_FILE_TYPE);
/* If a same alias has already been put, we ignore it */ return false;
if(aliases.containsKey(alias))
continue;
String server = line.substring(cut+1);
aliases.put(alias, server);
}
reader.close();
} }
catch(IOException e) 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 ```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 @GET
@Path("list") @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN) @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 )
{
FTPClient client = new FTPClient();
String response;
if(ClientUtil.connectAndLogin(client, server, port, username, password))
{ {
return LIST.execute(client); 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 ```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 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 = ""; String response = "";
try try
{ {
FTPFile[] files = client.listFiles(); client.enterLocalPassiveMode();
FTPFile[] files = client.listFiles(path);
for(FTPFile file : files) for(FTPFile file : files)
{ {
response += file.getName() + "\n"; response += file.getRawListing();
response += "\n";
} }
return response;
} }
catch(IOException e) catch(IOException e)
{ {
response = "The command \"" + NAME + "\" failed."; response = "An IO error occured while sending the command or receiving its result.";
} }
return response; 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 # Les tests
...@@ -193,10 +259,10 @@ Aucun test n'a été réalisé cette fois-ci. ...@@ -193,10 +259,10 @@ Aucun test n'a été réalisé cette fois-ci.
Les efforts ont été concentrés à rendre la plateforme fonctionnel. 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). J'aurais `rendu les retours encore plus précis` si une fonction n'avait pas rendu le résultat escompté.
\ No newline at end of file
</div></div></div></div>
<footer class="p-footer">
<div class="row">
<p><small>&copy; 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>
</div></div></div></div>
<footer class="p-footer">
<div class="row">
<p><small>&copy; 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>
</div></div></div></div>
<footer class="p-footer">
<div class="row">
<p><small>&copy; 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>
# 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
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <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"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>flopbox</groupId> <groupId>flopbox</groupId>
<artifactId>flopbox</artifactId> <artifactId>flopbox</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<name>flopbox</name> <name>flopbox</name>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
...@@ -21,11 +27,14 @@ ...@@ -21,11 +27,14 @@
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.glassfish.jersey.containers</groupId> <groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId> <artifactId>jersey-container-grizzly2-http</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.glassfish.jersey.inject</groupId> <groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId> <artifactId>jersey-hk2</artifactId>
...@@ -44,13 +53,6 @@ ...@@ -44,13 +53,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </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 --> <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency> <dependency>
<groupId>commons-net</groupId> <groupId>commons-net</groupId>
...@@ -59,6 +61,8 @@ ...@@ -59,6 +61,8 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
...@@ -71,6 +75,7 @@ ...@@ -71,6 +75,7 @@
<target>1.7</target> <target>1.7</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId> <artifactId>exec-maven-plugin</artifactId>
...@@ -103,8 +108,10 @@ ...@@ -103,8 +108,10 @@
</plugins> </plugins>
</build> </build>
<properties> <properties>
<jersey.version>3.0.1</jersey.version> <jersey.version>2.33</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
</project> </project>
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
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
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
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
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
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
package flopbox; package flopbox;
import flopbox.account.AccountUtil;
import org.apache.commons.net.ftp.FTPClient;
import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ResourceConfig;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/** /**
* Main class. * Main class.
*
*/ */
public class Main public class Main
{ {
/* URI the Grizzly HTTP server will listen on */ // Base URI the Grizzly HTTP server will listen on
private static String uri = "http://localhost:8080/myapp/"; public static final String BASE_URI = "http://localhost:8080/flopbox/";
/* 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);
}
...@@ -87,28 +32,7 @@ public class Main ...@@ -87,28 +32,7 @@ public class Main
// create and start a new instance of grizzly http server // create and start a new instance of grizzly http server
// exposing the Jersey application at BASE_URI // exposing the Jersey application at BASE_URI
return GrizzlyHttpServerFactory.createHttpServer(URI.create(uri), rc); return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_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();
} }
...@@ -122,25 +46,13 @@ public class Main ...@@ -122,25 +46,13 @@ public class Main
*/ */
public static void main(String[] args) throws IOException 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(); final HttpServer server = startServer();
System.out.println(String.format("Jersey app started with WADL available at " 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(); System.in.read();
/* Wait a word from the user to then shutdown the server */
// waitWord();
server.shutdownNow(); server.shutdownNow();
} }
} }
......
package flopbox; package flopbox;
import flopbox.client.ClientUtil;
import flopbox.command.*; 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 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 public class MyResource
{ {
private FTPClient client = Main.getClient();
private ServerSocket activeConnection;
/** /**
* Change to the parent directory. * Print the registered servers and their hosts.
* *
* @param client The FTP client. * @return the registered servers and their hosts.
*
* @return How the command went.
*/ */
@GET @GET
@Path("cdup")
@Produces(MediaType.TEXT_PLAIN) @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 server The server.
* @param address The address of the ftp server. * @param host The host of the server.
* @param port The port of the ftp server.
* *
* @return How the command went. * @return How the command went.
*/ */
@GET @PUT
@Path("connect:{address}:{port}") @Path("{server}")
@Produces(MediaType.TEXT_PLAIN) @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 server The server.
* @param pathname The pathname of the next working directory.
* *
* @return How the command went. * @return How the command went.
*/ */
@GET @DELETE
@Path("cwd:{pathname}") @Path("{server}")
@Produces(MediaType.TEXT_PLAIN) @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 server The server.
* @param pathname The pathname of a file. * @param host The new host of the server.
* *
* @return How the command went. * @return How the command went.
*/ */
@GET @PATCH
@Path("dele:{pathname}") @Path("{server}")
@Produces(MediaType.TEXT_PLAIN) @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. * Create 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 directory to create.
* *
* @return How the command went. * @return How the command went.
*/ */
@GET @PUT
@Path("list") @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN) @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))
/**
* 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); response = FtpCommands.makeDir(client, path);
ClientUtil.logoutAndDisconnect(client);
} }
else
return "The connection to the server failed.";
return response + "\n";
}
/** /**
* Make a new directory. * Delete a file or directory on the FTP server.
* *
* @param client The FTP client. * @param server The FTP server to connect to.
* @param pathname The pathname of the new directory. * @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. * @return How the command went.
*/ */
@GET @DELETE
@Path("mkd:{pathname}") @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN) @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))
* 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)
{ {
return PASV.execute(client); response = FtpCommands.delete(client, path);
ClientUtil.logoutAndDisconnect(client);
} }
else
return "The connection to the server failed.";
return response + "\n";
}
/** /**
* Enter in active mode. * Download a file.
* *
* @param client The FTP client. * @param server The FTP server to connect to.
* @param activeConnection The active connection. * @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. * @return How the command went.
*/ */
@GET @GET
@Path("port") @Path("{server}/{path:.*}/download")
@Produces(MediaType.TEXT_PLAIN) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
public String port(FTPClient client) public String download(@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))
* Print the working directory.
*
* @param client The FTP client.
*
* @return How the command went.
*/
@GET
@Path("pwd")
@Produces(MediaType.TEXT_PLAIN)
public String pwd(FTPClient client)
{ {
return PWD.execute(client); response = FtpCommands.download(client, path);
ClientUtil.logoutAndDisconnect(client);
} }
else
response = "The connection to the server failed.";
return response + "\n";
}
/** /**
* Disconnect from the server. * 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 @GET
@Path("quit") @Path("{server}/{path:.*}")
@Produces(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN)
public String quit() public String list(@PathParam ("server" ) String server , @HeaderParam("port" ) int port ,
@HeaderParam("username") String username, @HeaderParam("password") String password,
@PathParam ("path" ) String path )
{ {
return QUIT.execute(client); FTPClient client = new FTPClient();
}
String response;
/** if(ClientUtil.connectAndLogin(client, server, port, username, password))
* 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); response = FtpCommands.list(client, path);
ClientUtil.logoutAndDisconnect(client);
} }
else
response = "The connection to the server failed.";
return response;
}
/** /**
* Rename a file. * Rename a file or directory on the FTP server.
* *
* @param client The FTP client. * @param server The FTP server to connect to.
* @param oldFilename The old filename. * @param port The port of the FTP server to connect to.
* @param newFilename The new filename. * @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. * @return How the command went.
*/ */
@GET @PATCH
@Path("rn:{oldFilename}:{newFilename}") @Path("{server}/{from}")
@Produces(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN)
public String rn(FTPClient client, @PathParam("oldFilename") String oldFilename, @PathParam("newFilename") String newFilename) 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 RN.execute(client, oldFilename, newFilename); FTPClient client = new FTPClient();
}
String response;
/** if(ClientUtil.connectAndLogin(client, server, port, username, password))
* 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); response = FtpCommands.rename(client, from, to);
ClientUtil.logoutAndDisconnect(client);
} }
else
response = "The connection to the server failed.";
return response + "\n";
}
/** /**
* Set the type. * Store a file or directory on the FTP server.
* *
* @param client The FTP client. * @param server The FTP server to connect to.
* @param type The position of the desired type in the string of types. * @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. * @return How the command went.
*/ */
@GET @POST
@Path("type:{type}") @Path("{server}/{to:.*}/upload")
@Produces(MediaType.TEXT_PLAIN) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
public String type(FTPClient client, @PathParam("type") int type) 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 TYPE.execute(client, type); 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";
} }
} }
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
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;
}
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment