Merge branch 'benjamin' into dev

This commit is contained in:
Benjamin 2022-03-11 17:03:39 +01:00
commit a2e86eb02d
24 changed files with 142 additions and 32 deletions

View File

@ -3,7 +3,6 @@
*/
package lightcontainer;
import lightcontainer.domains.client.Context;
import lightcontainer.domains.server.MulticastServerListener;
import lightcontainer.domains.server.UnicastServerListener;
import lightcontainer.interfaces.ProtocolRepository;
@ -13,11 +12,8 @@ import lightcontainer.repository.ClientHandlerRepository;
import lightcontainer.repository.FileFrontEnd;
import lightcontainer.repository.ProtocolRepositoryImpl;
import lightcontainer.repository.StoreProcessorRepository;
import lightcontainer.storage.AppConfig;
import lightcontainer.storage.AppData;
import java.io.File;
public class App {
// Constant config server
// -- Unicast client port
@ -40,13 +36,13 @@ public class App {
protocolRep.addReader(new HelloRule());
protocolRep.addReader(new SigninRule(protocolRep));
protocolRep.addReader(new SignupRule(protocolRep));
protocolRep.addReader(new SignoutRule());
protocolRep.addReader(new FilelistRule(protocolRep));
protocolRep.addReader(new SavefileRule(protocolRep));
protocolRep.addReader(new SendOkRule(protocolRep));
protocolRep.addWriter(new SignOkRule());
protocolRep.addWriter(new SignErrorRule());
protocolRep.addWriter(new SignoutRule());
protocolRep.addWriter(new FilesRule());
protocolRep.addWriter(new SaveFileOkRule());
protocolRep.addWriter(new SaveFileErrorRule());

View File

@ -2,13 +2,16 @@ package lightcontainer.domains;
import lightcontainer.domains.client.Context;
import lightcontainer.enumerations.TaskStatus;
import lightcontainer.enumerations.TaskType;
import lightcontainer.protocol.ProtocolWriter;
/**
* Une tâche exécutable
*/
public class Task {
// Variables
private TaskStatus status;
private ProtocolWriter.ProtocolResult command;
private String storeDomain;
/**
@ -22,6 +25,12 @@ public class Task {
this.command = command;
}
/**
* Permet de créer une instance de la class {@link Task}
* @param context Context à utiliser pour cette tâche
* @param command Commande à exécuter
* @return L'instance de la tâche créée
*/
public static Task newInstance(Context context, ProtocolWriter.ProtocolResult command) {
Task task = new Task(context, TaskStatus.PENDING, command);
return task;
@ -44,10 +53,18 @@ public class Task {
return context.getLogin();
}
/**
* Permet de récupérer la commande à executer
* @return Commande à exécuter
*/
public ProtocolWriter.ProtocolResult getCommand() {
return this.command;
}
/**
* Permet de définir le StorBackEnd à utiliser pour cette tâche
* @param storeDomain Le StorBackEnd à utiliser
*/
public void setDomain(String storeDomain) {
this.storeDomain = storeDomain;
if (storeDomain != null) {

View File

@ -1,10 +1,13 @@
package lightcontainer.domains.client;
import lightcontainer.domains.server.UnicastServerListener;
import lightcontainer.interfaces.ClientHandlerFFE;
import lightcontainer.interfaces.ProtocolRepository;
import lightcontainer.interfaces.UnicastCHR;
import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.ProtocolWriter;
import lightcontainer.protocol.rules.reader.SigninRule;
import lightcontainer.protocol.rules.reader.SignoutRule;
import lightcontainer.protocol.rules.reader.SignupRule;
import lightcontainer.protocol.rules.writer.SignErrorRule;
import lightcontainer.protocol.rules.writer.SignOkRule;
@ -34,6 +37,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
private ProtocolRepository protocolRep;
private Context context;
private boolean client_run;
private UnicastCHR repository;
private BufferedReader reader;
@ -41,7 +45,8 @@ public class ClientHandler implements Runnable, AutoCloseable {
private ProtocolWriter.ProtocolResult response;
// Constructor
public ClientHandler(Socket client, ClientHandlerFFE ffe, ProtocolRepository protocolRep, Context context) {
public ClientHandler(UnicastCHR repository, Socket client, ClientHandlerFFE ffe, ProtocolRepository protocolRep, Context context) {
this.repository = repository;
this.fileFrontEnd = ffe;
this.client = client;
this.protocolRep = protocolRep;
@ -87,11 +92,13 @@ public class ClientHandler implements Runnable, AutoCloseable {
String command = this.reader.readLine();
if (command != null) {
System.out.println("Client: " + command);
} else this.client.close();
} else {
repository.disconnect(this);
}
ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(context, command + "\r\n");
if (ruleResult == null) {
this.close();
repository.disconnect(this);
return;
}
@ -120,6 +127,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
}
} catch (IOException ignore) {
ignore.printStackTrace();
repository.disconnect(this);
}
}
@ -131,6 +139,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
* @return TRUE si le client possède l'accès demandé
*/
private boolean checkAccess(ProtocolReader.ProtocolResult ruleResult) {
checkSignout(ruleResult);
if (context.isConnected())
return true;
@ -158,6 +167,17 @@ public class ClientHandler implements Runnable, AutoCloseable {
writer.flush();
}
/**
* Vérifie s'il s'âgit d'une demande de déconnexion
* @param ruleResult
*/
private void checkSignout(ProtocolReader.ProtocolResult ruleResult) {
try {
ruleResult.getClass().asSubclass(SignoutRule.Result.class);
repository.disconnect(this);
} catch (ClassCastException e2) { }
}
/**
* Permet au Client d'attendre la fin de la réalisation de sa tâche
*/
@ -194,6 +214,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
try {
this.client_run = false;
this.client.close();
System.out.printf("[CLIENT] %s s'est déconnecté\n", context.getLogin());
} catch (IOException ignored) { }
}
}

View File

@ -7,6 +7,10 @@ import lightcontainer.utils.AES_GCM;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
/**
* Contexte associé à la requête d'un utilisateur.
* Permet de récupérer les données à celui-ci et d'effectuer des actions sur le context courant.
*/
public class Context {
private AppData appData;
@ -16,12 +20,18 @@ public class Context {
*/
private String login;
// Constructeur
public Context(AppData appData) {
this.appData = appData;
}
/**
* Permet de créer un utilisateur.
* @param login Login de l'utilisateur
* @param password Mot de passe de l'utilisateur
* @return TRUE si l'utilisateur a pu être créé
*/
public boolean createUser(String login, String password) {
try {
String key = AES_GCM.generateSecretKey();

View File

@ -51,7 +51,7 @@ public class UnicastServerListener implements Runnable {
Socket client = this.server.accept();
System.out.println("New Client");
// Create a new Handler client by passing these dependencies to it
ClientHandler clientHandler = new ClientHandler(client, ffe, protocolRep, new Context(AppData.getInstance())); // TODO passer FileFrontEnd ou faire ca dans le repository ?!
ClientHandler clientHandler = new ClientHandler(this.repository, client, ffe, protocolRep, new Context(AppData.getInstance()));
// Add the client handler to its repository (clienthandlerrepository)
this.repository.addClient(clientHandler);
// Start the thread

View File

@ -22,5 +22,11 @@ public interface UnicastCHR {
*/
void addClient(ClientHandler client);
/**
* Permet de demander la déconnection d'un client
* @param client Le client à déconnecter
*/
void disconnect(ClientHandler client);
void respondToClient(String client, ProtocolWriter.ProtocolResult response);
}

View File

@ -6,6 +6,9 @@ import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Permet de construire des règles ayant pour but de parser une commande en un résultat utilisable par celle-ci
*/
public abstract class ProtocolReader {
private final String name;
// Variables

View File

@ -6,6 +6,9 @@ import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Représente une construction de tâche.
*/
public abstract class ProtocolWriter {
// Variables
private final Pattern rulePattern;

View File

@ -7,6 +7,9 @@ import lightcontainer.protocol.ProtocolWriter;
import lightcontainer.protocol.rules.writer.FilesRule;
import lightcontainer.protocol.rules.writer.SignOkRule;
/**
* Règle permettant de récupérer la liste des fichiers d'un utilisateur
*/
public class FilelistRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^FILELIST\r\n$";

View File

@ -7,6 +7,9 @@ import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.List;
/**
* Règle permettant d'être alerter de l'annoncement d'un SBE
*/
public class HelloRule extends ProtocolReader {
private static final String PATTERN = "^HELLO ([A-Za-z0-9]{5,20}) ([0-9]{1,5})\r\n$";

View File

@ -13,6 +13,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
/**
* Règle permettant de sauvegarder un fichier sur le SBE.
* Celui-ci va chiffre le contenu du fichier à l'aide de AES.
*/
public class SavefileRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^SAVEFILE ([^ !]{1,20}) ([0-9]{1,10})\r\n$";

View File

@ -6,6 +6,9 @@ import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.ProtocolWriter;
import lightcontainer.protocol.rules.writer.SaveFileOkRule;
/**
* Règle permettant de de confirmer la sauvegrade d'un fichier.
*/
public class SendOkRule extends ProtocolReader {

View File

@ -10,6 +10,9 @@ import lightcontainer.protocol.rules.writer.SignOkRule;
import java.io.InputStream;
/**
* Règle permettant de gérer la connection d'un utilisateur
*/
public class SigninRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^SIGNIN ([A-Za-z0-9]{5,20}) ([^ !]{5,50})\r\n$";

View File

@ -0,0 +1,31 @@
package lightcontainer.protocol.rules.reader;
import lightcontainer.domains.client.Context;
import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle demandant la déconnexion du client
*/
public class SignoutRule extends ProtocolReader {
private static final String PATTERN = "^SIGNOUT\r\n$";
public static final String NAME = "SIGNOUT";
public SignoutRule() {
super(NAME, PATTERN);
}
public class Result extends ProtocolResult {
public Result(Context context) {
super(context);
}
}
@Override
protected <T extends ProtocolResult> T onExecuted(Context context, String... data) {
return null;
}
}

View File

@ -6,6 +6,9 @@ import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.rules.writer.SignErrorRule;
import lightcontainer.protocol.rules.writer.SignOkRule;
/**
* Règle permettant de gérer la création d'un utilisateur
*/
public class SignupRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^SIGNUP ([A-Za-z0-9]{5,20}) ([^ !]{5,50})\r\n$";

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle permettant de construire une commande contenant la liste des fichiers d'un utilisateur
*/
public class FilesRule extends ProtocolWriter {
private static final String PATTERN = "^FILES( ([^ !]{1,20})!([0-9]{1,10})){0,50}\r\n$";

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle signifiant que la sauvegarde d'un fichier a échoué
*/
public class SaveFileErrorRule extends ProtocolWriter {
private static final String PATTERN = "^SAVEFILE_ERROR\r\n$";

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle signifiant que la sauvegarde d'un fichier fût un succès
*/
public class SaveFileOkRule extends ProtocolWriter {
private static final String PATTERN = "^SAVEFILE_OK\r\n$";

View File

@ -6,6 +6,9 @@ import lightcontainer.utils.FileSender;
import java.io.OutputStream;
/**
* Règle envoyée au SBE, demandant la sauvegarde d'un fichier.
*/
public class SendfileRule extends ProtocolWriter {
private static final String PATTERN = "^SENDFILE [A-Za-z0-9.]{0,200} [0-9]{1,10} [A-Za-z0-9.]{50,200}\r\n$";

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle renvoyée au client lorsque l'authentification a échoué.
*/
public class SignErrorRule extends ProtocolWriter {
private static final String PATTERN = "^SIGN_ERROR\r\n$";

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle renvoyée au client lorsque l'authentification a réusie.
*/
public class SignOkRule extends ProtocolWriter {
private static final String PATTERN = "^SIGN_OK\r\n$";

View File

@ -1,14 +0,0 @@
package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
public class SignoutRule extends ProtocolWriter {
private static final String PATTERN = "^SIGNOUT\r\n$";
public static final String NAME = "SIGNOUT";
public SignoutRule() {
super(NAME, PATTERN);
}
}

View File

@ -55,6 +55,12 @@ public class ClientHandlerRepository implements AutoCloseable, UnicastCHR {
this.handlers.add(client);
}
@Override
public void disconnect(ClientHandler client) {
if (handlers.remove(client))
client.close();
}
@Override
public void respondToClient(String login, ProtocolWriter.ProtocolResult response) {
for (ClientHandler client : handlers) {

View File

@ -1,6 +1,7 @@
package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
import lightcontainer.protocol.rules.reader.SignoutRule;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@ -9,13 +10,6 @@ class SignoutRuleTest {
@Test
public void whenRuleIsRightThenReturnCommand() {
//GIVEN
ProtocolWriter protocolWriter = new SignoutRule();
String[] datas = {};
//EXPECT
assertNotNull(protocolWriter.execute(datas));
assertEquals("SIGNOUT\r\n", protocolWriter.execute(datas));
}
}