Merge branch 'jeremi' into dev

# Conflicts:
#	app/src/main/resources/appdata.json
This commit is contained in:
Jérémi N ‘EndMove’ 2022-03-12 22:16:46 +01:00
commit a9a620275d
Signed by: EndMove
GPG Key ID: 65C4A02E1F5371A4
17 changed files with 256 additions and 61 deletions

View File

@ -16,9 +16,6 @@ import lightcontainer.storage.AppData;
import lightcontainer.storage.JsonAdapter; import lightcontainer.storage.JsonAdapter;
import lightcontainer.storage.Repository; import lightcontainer.storage.Repository;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
public class App { public class App {
@ -39,6 +36,7 @@ public class App {
protocolRep.addReader(new FilelistRule(protocolRep)); protocolRep.addReader(new FilelistRule(protocolRep));
protocolRep.addReader(new SavefileRule(protocolRep, repositoryStorage.getStoragePath())); protocolRep.addReader(new SavefileRule(protocolRep, repositoryStorage.getStoragePath()));
protocolRep.addReader(new SendOkRule(protocolRep)); protocolRep.addReader(new SendOkRule(protocolRep));
protocolRep.addReader(new GetFileRule(protocolRep));
protocolRep.addWriter(new SignOkRule()); protocolRep.addWriter(new SignOkRule());
protocolRep.addWriter(new SignErrorRule()); protocolRep.addWriter(new SignErrorRule());
@ -46,6 +44,7 @@ public class App {
protocolRep.addWriter(new SaveFileOkRule()); protocolRep.addWriter(new SaveFileOkRule());
protocolRep.addWriter(new SaveFileErrorRule()); protocolRep.addWriter(new SaveFileErrorRule());
protocolRep.addWriter(new SendfileRule(repositoryStorage.getStoragePath())); protocolRep.addWriter(new SendfileRule(repositoryStorage.getStoragePath()));
protocolRep.addWriter(new GetFileErrorRule());
FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep); FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep);
new UnicastServerListener(ffe, clientRep, protocolRep, repositoryStorage, repositoryStorage.getUnicastPort()); new UnicastServerListener(ffe, clientRep, protocolRep, repositoryStorage, repositoryStorage.getUnicastPort());

View File

@ -132,8 +132,8 @@ public class ClientHandler implements Runnable, AutoCloseable {
System.out.println(4); System.out.println(4);
accessDenied(); accessDenied();
} }
} catch (IOException ignore) { } catch (IOException e) {
ignore.printStackTrace(); e.printStackTrace();
repository.disconnect(this); repository.disconnect(this);
break; break;
} }

View File

@ -1,14 +1,10 @@
package lightcontainer.domains.client; package lightcontainer.domains.client;
import lightcontainer.storage.AppData;
import lightcontainer.storage.File; import lightcontainer.storage.File;
import lightcontainer.storage.Repository; import lightcontainer.storage.Repository;
import lightcontainer.storage.User;
import lightcontainer.utils.AES_GCM; import lightcontainer.utils.AES_GCM;
import lightcontainer.utils.ShaHasher; import lightcontainer.utils.ShaHasher;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -17,9 +13,8 @@ import java.util.Set;
* Permet de récupérer les données à celui-ci et d'effectuer des actions sur le context courant. * Permet de récupérer les données à celui-ci et d'effectuer des actions sur le context courant.
*/ */
public class Context { public class Context {
// Variables
private Repository repository; private final Repository repository;
private RequestBundle requestBundle; private RequestBundle requestBundle;
/** /**
@ -57,8 +52,7 @@ public class Context {
this.login = login; this.login = login;
return true; return true;
} }
} catch (AES_GCM.AesGcmException e) { } catch (AES_GCM.AesGcmException ignored) { }
}
return false; return false;
} }
@ -172,6 +166,10 @@ public class Context {
return this.repository.addFileFor(new File(fileName, fileNameSalt, size, iv, Set.of(domain)), getLogin()); return this.repository.addFileFor(new File(fileName, fileNameSalt, size, iv, Set.of(domain)), getLogin());
} }
public File getFileOf(String fileName, String userName) {
return this.repository.getFileOf(fileName, userName);
}
public List<String> getStringifiedFilesOf() { public List<String> getStringifiedFilesOf() {
return repository.getStringifiedFilesOf(login); return repository.getStringifiedFilesOf(login);
} }

View File

@ -1,6 +1,5 @@
package lightcontainer.domains.client; package lightcontainer.domains.client;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

View File

@ -20,6 +20,7 @@ public abstract class ProtocolReader {
this.rulePattern = Pattern.compile(pattern); this.rulePattern = Pattern.compile(pattern);
} }
// Receiver list
public enum ResultCmdReceiver { public enum ResultCmdReceiver {
CLIENT, CLIENT,
STOREBACKEND STOREBACKEND
@ -39,7 +40,7 @@ public abstract class ProtocolReader {
/** /**
* Le context courant * Le context courant
*/ */
private Context context; private final Context context;
public ProtocolResult(Context context) { public ProtocolResult(Context context) {
this.context = context; this.context = context;
@ -52,6 +53,11 @@ public abstract class ProtocolReader {
*/ */
private ResultCmdReceiver receiver; private ResultCmdReceiver receiver;
/**
* Récupérer le destinataire
*
* @return Receiver
*/
public ResultCmdReceiver getReceiver() { public ResultCmdReceiver getReceiver() {
return receiver; return receiver;
} }
@ -123,18 +129,17 @@ public abstract class ProtocolReader {
private String extractName(String data) { private String extractName(String data) {
String name; String name;
int endIndex = data.indexOf(' '); int endIndex = data.indexOf(' ');
if (endIndex > 0) { if (endIndex <= 0) {
name = data.substring(0, endIndex);
} else {
endIndex = data.indexOf('\r'); endIndex = data.indexOf('\r');
name = data.substring(0, endIndex);
} }
name = data.substring(0, endIndex);
return name; return name;
} }
/** /**
* Cette méthode est appelée lors de l'exécution de la règle * Cette méthode est appelée lors de l'exécution de la règle
* *
* @param context Utilisateur context.
* @param data Paramètres pour créer la commande. * @param data Paramètres pour créer la commande.
*/ */
protected abstract <T extends ProtocolResult> T onExecuted(Context context, String... data); protected abstract <T extends ProtocolResult> T onExecuted(Context context, String... data);

View File

@ -0,0 +1,70 @@
package lightcontainer.protocol.rules.reader;
import lightcontainer.domains.client.Context;
import lightcontainer.interfaces.ProtocolRepository;
import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.rules.writer.GetFileErrorRule;
import lightcontainer.storage.File;
public class GetFileRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^GETFILE ([^ !]{1,20})\r\n$";
private static final String NAME = "GETFILE";
// -- arguments
private static final int FILE_NAME = 0; // Index file name.
// Variables
private final ProtocolRepository protocolRep;
// Constructor
public GetFileRule(ProtocolRepository protocolRep) {
super(NAME, PATTERN);
this.protocolRep = protocolRep;
}
/**
* Rule Result
*/
public class Result extends ProtocolResult {
// Variables
private final String fileName;
// Constructor
public Result(Context context, String fileName) {
super(context);
this.fileName = fileName;
}
}
/**
* Cette méthode est appelée lors de l'exécution de la règle
*
* @param context Utilisateur context.
* @param data Paramètres pour créer la commande.
*/
@Override
protected GetFileRule.Result onExecuted(Context context, String... data) {
GetFileRule.Result result = new GetFileRule.Result(context, data[FILE_NAME]);
File file = context.getFileOf(data[FILE_NAME], context.getLogin());
if (true) {
} else {
}
return result;
}
/**
* Cette méthode est appelée lors d'une erreur de la règle
*/
protected ProtocolReader.ProtocolResult onError(Context context) {
ProtocolReader.ProtocolResult result = new ProtocolReader.ProtocolResult(context);
// Make getFileErrorRule
result.setResultCommand(protocolRep.executeWriter(context, GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT);
return result;
}
}

View File

@ -0,0 +1,26 @@
package lightcontainer.protocol.rules.reader;
import lightcontainer.domains.client.Context;
import lightcontainer.protocol.ProtocolReader;
public class RetrieveErrorRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^RETRIEVE_ERROR\r\n$";
private static final String NAME = "RETRIEVE_ERROR";
// Constructor
protected RetrieveErrorRule() {
super(NAME, PATTERN);
}
/**
* Cette méthode est appelée lors de l'exécution de la règle
*
* @param context Utilisateur context.
* @param data Paramètres pour créer la commande.
*/
@Override
protected <T extends ProtocolResult> T onExecuted(Context context, String... data) {
return null;
}
}

View File

@ -0,0 +1,35 @@
package lightcontainer.protocol.rules.reader;
import lightcontainer.domains.client.Context;
import lightcontainer.protocol.ProtocolReader;
public class RetrieveOkRule extends ProtocolReader {
// Constants
private static final String PATTERN = "^RETRIEVE_OK ([A-Za-z0-9.]{50,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$";
private static final String NAME = "RETRIEVE_OK";
// -- arguments
private static final int HASHED_FILE_NAME = 0; // Index hashed filename
private static final int FILE_SIZE = 1; // Index file size
private static final int HASHED_FILE_CONTENT = 2; // Index hashed file content
// Variables
protected RetrieveOkRule() {
super(NAME, PATTERN);
}
/**
* Cette méthode est appelée lors de l'exécution de la règle
*
* @param context Utilisateur context.
* @param data Paramètres pour créer la commande.
*/
@Override
protected <T extends ProtocolResult> T onExecuted(Context context, String... data) {
return null;
}
@Override
protected <T extends ProtocolResult> T onError(Context context) {
return super.onError(context);
}
}

View File

@ -0,0 +1,18 @@
package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
/**
* Règle utilisé dans le cas ou une erreur survient lors
* de la demande de récupération d'un fichier.
*/
public class GetFileErrorRule extends ProtocolWriter {
// Constants
private static final String PATTERN = "^GETFILE_ERROR\r\n$";
public static final String NAME = "GETFILE_ERROR";
// Constructors
public GetFileErrorRule() {
super(NAME, PATTERN);
}
}

View File

@ -0,0 +1,17 @@
package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
public class GetFileOkRule extends ProtocolWriter {
// Constants
private static final String PATTERN = "^GETFILE_OK (^ !]{1,20}) ([0-9]{1,10})\r\n)$";
public static final String NAME = "GETFILE_OK";
// -- params
private static final int FILE_NAME = 0; // Index file name hashed
private static final int FILE_SIZE = 1; // Index file size
// Constructors
protected GetFileOkRule() {
super(NAME, PATTERN);
}
}

View File

@ -0,0 +1,16 @@
package lightcontainer.protocol.rules.writer;
import lightcontainer.protocol.ProtocolWriter;
public class RetrieveFileRule extends ProtocolWriter {
// Constants
private static final String PATTERN = "^RETRIEVEFILE ([A-Za-z0-9.]{50,200})\r\n$";
public static final String NAME = "RETRIEVEFILE";
// -- params
private static final int HASHED_FILE_NAME = 0; // Index hashed filename
// Constructor
protected RetrieveFileRule() {
super(NAME, PATTERN);
}
}

View File

@ -52,7 +52,6 @@ public class SendfileRule extends ProtocolWriter {
} }
} }
@Override @Override
protected SendfileRule.Result onExecuted(Context context, String... data) { protected SendfileRule.Result onExecuted(Context context, String... data) {
return new SendfileRule.Result(context, data[HASHED_FILE_NAME], Integer.parseInt(data[FILE_SIZE]), data[HASHED_FILE_CONTENT]); return new SendfileRule.Result(context, data[HASHED_FILE_NAME], Integer.parseInt(data[FILE_SIZE]), data[HASHED_FILE_CONTENT]);

View File

@ -16,12 +16,11 @@ import java.util.Map;
* @since 1.0 * @since 1.0
*/ */
public class AppData { public class AppData {
// Variable
private static AppData instance = null; private static AppData instance = null;
private AppConfig appConfig; private AppConfig appConfig;
private final Map<String, User> users; private final Map<String, User> users;
/** /**
* Constructs a new instance of AppData. * Constructs a new instance of AppData.
* Sets appConfig to null and creates a new Hashmap of users. * Sets appConfig to null and creates a new Hashmap of users.
@ -76,7 +75,6 @@ public class AppData {
return null; return null;
} }
/** /**
* Use this method when a user signs up. * Use this method when a user signs up.
* *
@ -138,6 +136,26 @@ public class AppData {
} }
} }
/**
* Getter, allow to retrieve a specified file object.
*
* @param fileName The name of the file to retrieve.
* @param userName The name of the user who wants to retrieve the file.
* @return The requested file matching file name and username, or null
* if the user or file do not exist.
*
* @see User#getFile(String)
* @see File
*
* @author Unknown...
*/
public File getFileOf(String fileName, String userName) {
if (this.users.containsKey(userName)) {
return this.users.get(userName).getFile(fileName);
}
return null;
}
/** /**
* Call this method after receiving REMOVEFILE_OK from the StorBackEnd. * Call this method after receiving REMOVEFILE_OK from the StorBackEnd.
* Do NOT call when receiving REMOVEFILE_ERROR, or it will break the system's synchronization. * Do NOT call when receiving REMOVEFILE_ERROR, or it will break the system's synchronization.
@ -181,7 +199,6 @@ public class AppData {
return user == null ? null : user.getPasswordSalt(); return user == null ? null : user.getPasswordSalt();
} }
/** /**
* Méthode permettant de récupérer la clé AES d'un utilisateur * Méthode permettant de récupérer la clé AES d'un utilisateur
* *
@ -192,5 +209,4 @@ public class AppData {
User user = getUser(login); User user = getUser(login);
return user == null ? null : user.getAesKey(); return user == null ? null : user.getAesKey();
} }
} }

View File

@ -7,13 +7,14 @@ import java.util.Set;
* File represents all information related to a file * File represents all information related to a file
*/ */
public class File { public class File {
// Variables
private final String name; private final String name;
private final String fileNameSalt; private final String fileNameSalt;
private final int size; private final int size;
private final String iv; private final String iv;
private final Set<String> storage; private final Set<String> storage;
// Constructor
public File(String name, String fileNameSalt, int size, String iv, Set<String> storage) { public File(String name, String fileNameSalt, int size, String iv, Set<String> storage) {
this.name = name; this.name = name;
this.fileNameSalt = fileNameSalt; this.fileNameSalt = fileNameSalt;
@ -50,6 +51,5 @@ public class File {
return true; return true;
} }
} }
} }

View File

@ -10,7 +10,7 @@ import java.nio.file.StandardOpenOption;
import java.util.List; import java.util.List;
public class Repository { public class Repository {
// Variables
private final String filePath; private final String filePath;
private final Adapter adapter; private final Adapter adapter;
private final AppData appData; private final AppData appData;
@ -76,7 +76,6 @@ public class Repository {
return false; return false;
} }
/** /**
* Loads configuration file * Loads configuration file
* *
@ -139,6 +138,22 @@ public class Repository {
return appData.getUserAesKey(login); return appData.getUserAesKey(login);
} }
/**
* Getter, allow to retrieve a specified file object.
*
* @param fileName The name of the file to retrieve.
* @param userName The name of the user who wants to retrieve the file.
* @return The requested file matching file name and username, or null
* if the user or file do not exist.
*
* @see AppData#getFileOf(String, String)
* @see File
*
* @author Unknown...
*/
public File getFileOf(String fileName, String userName) {
return this.appData.getFileOf(fileName, userName);
}
public List<String> getStringifiedFilesOf(String login) { public List<String> getStringifiedFilesOf(String login) {
return this.appData.getStringifiedFilesOf(login); return this.appData.getStringifiedFilesOf(login);

View File

@ -13,13 +13,14 @@ import java.util.Map;
* @since 1.0 * @since 1.0
*/ */
public class User { public class User {
// Variables
private final String name; private final String name;
private final String password; private final String password;
private final String aesKey; private final String aesKey;
private final String passwordSalt; private final String passwordSalt;
private final Map<String, File> files; private final Map<String, File> files;
// Constructor
public User(String name, String password, String aesKey, String passwordSalt, Map<String, File> files) { public User(String name, String password, String aesKey, String passwordSalt, Map<String, File> files) {
this.name = name; this.name = name;
this.password = password; this.password = password;
@ -109,5 +110,4 @@ public class User {
public boolean verifyPassword(String password) { public boolean verifyPassword(String password) {
return this.password.equals(password); return this.password.equals(password);
} }
} }

View File

@ -4,7 +4,7 @@
"multicast_port": 15502, "multicast_port": 15502,
"network_interface": "My network interface", "network_interface": "My network interface",
"tls": true, "tls": true,
"storagePath": "/home/benjamin/ffe", "storagePath": "D:\\ffe",
"users": [ "users": [
{ {
"name": "endmove", "name": "endmove",
@ -13,28 +13,19 @@
"passwordSalt": "ItYiXkwPa84Gwb6dGHQvXQ==", "passwordSalt": "ItYiXkwPa84Gwb6dGHQvXQ==",
"files": [ "files": [
{ {
"name": "ca.crt", "name": "HELMo.png",
"fileNameSalt": "aLLsH6DvoSUj7o8oGuBxhw==", "fileNameSalt": "tadvzRunAGiu0Z059eBPLQ==",
"size": 4207, "size": 130146,
"iv": "MShYLgwYd8SHDK6FifpORg==", "iv": "26s0BqNqVSbzN1lASkUzgQ==",
"storage": [ "storage": [
"lightcontainerSB01" "lightcontainerSB01"
] ]
}, },
{ {
"name": "main.py", "name": "apache2.conf",
"fileNameSalt": "mtyoHXGKxT0DL+1EF+RhSw==", "fileNameSalt": "C5GNkws8l2HrhIdF7gmG6w==",
"size": 854, "size": 12648,
"iv": "tnJyZHlVvboRl8uD9HWDow==", "iv": "hQx69qQj1ynaxZZ9wAxpbA==",
"storage": [
"lightcontainerSB01"
]
},
{
"name": "README.md",
"fileNameSalt": "ZpiL943DSaBgBbLXNsw1rw==",
"size": 17,
"iv": "1eDj0cCSHWGZzBG96ugR1A==",
"storage": [ "storage": [
"lightcontainerSB01" "lightcontainerSB01"
] ]
@ -49,9 +40,9 @@
"files": [ "files": [
{ {
"name": "ca.crt", "name": "ca.crt",
"fileNameSalt": "woKUXAfV5cNodEH8O7h5kA==", "fileNameSalt": "Mjo7iQeEl2PYX1RDUZbSlQ==",
"size": 4207, "size": 4207,
"iv": "Cy3rbfGdXuLf0aT+LS1wsA==", "iv": "uALI+Feo1lIg1lBxbCMwIQ==",
"storage": [ "storage": [
"lightcontainerSB01" "lightcontainerSB01"
] ]
@ -64,15 +55,6 @@
"storage": [ "storage": [
"lightcontainerSB01" "lightcontainerSB01"
] ]
},
{
"name": "README.md",
"fileNameSalt": "/upxjjFW8GUayXngbfV3fA==",
"size": 17,
"iv": "QCkcjqYsUfWAE0klUTVTzQ==",
"storage": [
"lightcontainerSB01"
]
} }
] ]
} }