diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java index 9ac6afc..ad7dd73 100644 --- a/app/src/main/java/lightcontainer/App.java +++ b/app/src/main/java/lightcontainer/App.java @@ -16,9 +16,6 @@ import lightcontainer.storage.AppData; import lightcontainer.storage.JsonAdapter; import lightcontainer.storage.Repository; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; public class App { @@ -39,6 +36,7 @@ public class App { protocolRep.addReader(new FilelistRule(protocolRep)); protocolRep.addReader(new SavefileRule(protocolRep, repositoryStorage.getStoragePath())); protocolRep.addReader(new SendOkRule(protocolRep)); + protocolRep.addReader(new GetFileRule(protocolRep)); protocolRep.addWriter(new SignOkRule()); protocolRep.addWriter(new SignErrorRule()); @@ -46,6 +44,7 @@ public class App { protocolRep.addWriter(new SaveFileOkRule()); protocolRep.addWriter(new SaveFileErrorRule()); protocolRep.addWriter(new SendfileRule(repositoryStorage.getStoragePath())); + protocolRep.addWriter(new GetFileErrorRule()); FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep); new UnicastServerListener(ffe, clientRep, protocolRep, repositoryStorage, repositoryStorage.getUnicastPort()); diff --git a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java index 1c9922a..d10a544 100644 --- a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java +++ b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java @@ -132,8 +132,8 @@ public class ClientHandler implements Runnable, AutoCloseable { System.out.println(4); accessDenied(); } - } catch (IOException ignore) { - ignore.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); repository.disconnect(this); break; } diff --git a/app/src/main/java/lightcontainer/domains/client/Context.java b/app/src/main/java/lightcontainer/domains/client/Context.java index 31fee1a..0df8787 100644 --- a/app/src/main/java/lightcontainer/domains/client/Context.java +++ b/app/src/main/java/lightcontainer/domains/client/Context.java @@ -1,14 +1,10 @@ package lightcontainer.domains.client; -import lightcontainer.storage.AppData; import lightcontainer.storage.File; import lightcontainer.storage.Repository; -import lightcontainer.storage.User; import lightcontainer.utils.AES_GCM; import lightcontainer.utils.ShaHasher; -import java.security.NoSuchAlgorithmException; -import java.util.LinkedList; import java.util.List; 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. */ public class Context { - - private Repository repository; - + // Variables + private final Repository repository; private RequestBundle requestBundle; /** @@ -57,8 +52,7 @@ public class Context { this.login = login; return true; } - } catch (AES_GCM.AesGcmException e) { - } + } catch (AES_GCM.AesGcmException ignored) { } return false; } @@ -172,6 +166,10 @@ public class Context { 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 getStringifiedFilesOf() { return repository.getStringifiedFilesOf(login); } diff --git a/app/src/main/java/lightcontainer/domains/client/RequestBundle.java b/app/src/main/java/lightcontainer/domains/client/RequestBundle.java index 20098c0..8e32156 100644 --- a/app/src/main/java/lightcontainer/domains/client/RequestBundle.java +++ b/app/src/main/java/lightcontainer/domains/client/RequestBundle.java @@ -1,6 +1,5 @@ package lightcontainer.domains.client; - import java.util.HashMap; import java.util.Map; diff --git a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java index ebace44..133a820 100644 --- a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java +++ b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java @@ -20,6 +20,7 @@ public abstract class ProtocolReader { this.rulePattern = Pattern.compile(pattern); } + // Receiver list public enum ResultCmdReceiver { CLIENT, STOREBACKEND @@ -39,7 +40,7 @@ public abstract class ProtocolReader { /** * Le context courant */ - private Context context; + private final Context context; public ProtocolResult(Context context) { this.context = context; @@ -52,6 +53,11 @@ public abstract class ProtocolReader { */ private ResultCmdReceiver receiver; + /** + * Récupérer le destinataire + * + * @return Receiver + */ public ResultCmdReceiver getReceiver() { return receiver; } @@ -123,18 +129,17 @@ public abstract class ProtocolReader { private String extractName(String data) { String name; int endIndex = data.indexOf(' '); - if (endIndex > 0) { - name = data.substring(0, endIndex); - } else { + if (endIndex <= 0) { endIndex = data.indexOf('\r'); - name = data.substring(0, endIndex); } + name = data.substring(0, endIndex); return name; } /** * 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. */ protected abstract T onExecuted(Context context, String... data); diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java new file mode 100644 index 0000000..6015a90 --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java @@ -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; + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java new file mode 100644 index 0000000..6483db2 --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java @@ -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 onExecuted(Context context, String... data) { + return null; + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java new file mode 100644 index 0000000..67a3149 --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java @@ -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 onExecuted(Context context, String... data) { + return null; + } + + @Override + protected T onError(Context context) { + return super.onError(context); + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileErrorRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileErrorRule.java new file mode 100644 index 0000000..4a963d6 --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileErrorRule.java @@ -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); + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java new file mode 100644 index 0000000..77bc6f5 --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java @@ -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); + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java new file mode 100644 index 0000000..d99241c --- /dev/null +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java @@ -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); + } +} diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java index 850c600..3bb8ef6 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java @@ -52,7 +52,6 @@ public class SendfileRule extends ProtocolWriter { } } - @Override 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]); diff --git a/app/src/main/java/lightcontainer/storage/AppData.java b/app/src/main/java/lightcontainer/storage/AppData.java index d0d188b..153ea0e 100644 --- a/app/src/main/java/lightcontainer/storage/AppData.java +++ b/app/src/main/java/lightcontainer/storage/AppData.java @@ -16,12 +16,11 @@ import java.util.Map; * @since 1.0 */ public class AppData { - + // Variable private static AppData instance = null; private AppConfig appConfig; private final Map users; - /** * Constructs a new instance of AppData. * Sets appConfig to null and creates a new Hashmap of users. @@ -76,7 +75,6 @@ public class AppData { return null; } - /** * 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. * 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(); } - /** * Méthode permettant de récupérer la clé AES d'un utilisateur * @@ -192,5 +209,4 @@ public class AppData { User user = getUser(login); return user == null ? null : user.getAesKey(); } - } diff --git a/app/src/main/java/lightcontainer/storage/File.java b/app/src/main/java/lightcontainer/storage/File.java index 9429cf9..c610a07 100644 --- a/app/src/main/java/lightcontainer/storage/File.java +++ b/app/src/main/java/lightcontainer/storage/File.java @@ -7,13 +7,14 @@ import java.util.Set; * File represents all information related to a file */ public class File { - + // Variables private final String name; private final String fileNameSalt; private final int size; private final String iv; private final Set storage; + // Constructor public File(String name, String fileNameSalt, int size, String iv, Set storage) { this.name = name; this.fileNameSalt = fileNameSalt; @@ -50,6 +51,5 @@ public class File { return true; } } - } diff --git a/app/src/main/java/lightcontainer/storage/Repository.java b/app/src/main/java/lightcontainer/storage/Repository.java index 81720c5..43dd38f 100644 --- a/app/src/main/java/lightcontainer/storage/Repository.java +++ b/app/src/main/java/lightcontainer/storage/Repository.java @@ -10,7 +10,7 @@ import java.nio.file.StandardOpenOption; import java.util.List; public class Repository { - + // Variables private final String filePath; private final Adapter adapter; private final AppData appData; @@ -76,7 +76,6 @@ public class Repository { return false; } - /** * Loads configuration file * @@ -139,6 +138,22 @@ public class Repository { 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 getStringifiedFilesOf(String login) { return this.appData.getStringifiedFilesOf(login); diff --git a/app/src/main/java/lightcontainer/storage/User.java b/app/src/main/java/lightcontainer/storage/User.java index 13ccbb2..80d517b 100644 --- a/app/src/main/java/lightcontainer/storage/User.java +++ b/app/src/main/java/lightcontainer/storage/User.java @@ -13,13 +13,14 @@ import java.util.Map; * @since 1.0 */ public class User { - + // Variables private final String name; private final String password; private final String aesKey; private final String passwordSalt; private final Map files; + // Constructor public User(String name, String password, String aesKey, String passwordSalt, Map files) { this.name = name; this.password = password; @@ -109,5 +110,4 @@ public class User { public boolean verifyPassword(String password) { return this.password.equals(password); } - } diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index 8a76dfd..48d6ee8 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1 +1,62 @@ -{"unicast_port":8000,"multicast_ip":"226.66.66.1","multicast_port":15502,"network_interface":"My network interface","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"endmove","password":"1f82407cace28cd7d97d23f82e8235d9da97575d033a12334fc71d3517f6a90fa04af829df3c722c38d3b68842e4ca2b","aes_key":"p0G+iViPp656O6aMKgcXSDT/e9/00wQH/ztUWf4tyr4=","passwordSalt":"ItYiXkwPa84Gwb6dGHQvXQ==","files":[]},{"name":"aaaaa","password":"5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617","aes_key":"qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=","passwordSalt":"Ns8Al6DpqPsIDlCSRBVTEg==","files":[{"name":"ca.crt","fileNameSalt":"Mjo7iQeEl2PYX1RDUZbSlQ==","size":4207,"iv":"uALI+Feo1lIg1lBxbCMwIQ==","storage":["lightcontainerSB01"]},{"name":"main.py","fileNameSalt":"YRwnBiXINCJ+zyxwADgNRQ==","size":854,"iv":"9LXrJFtcgU4DeUBghc4Dgw==","storage":["lightcontainerSB01"]}]}]} \ No newline at end of file +{ + "unicast_port": 8000, + "multicast_ip": "226.66.66.1", + "multicast_port": 15502, + "network_interface": "My network interface", + "tls": true, + "storagePath": "D:\\ffe", + "users": [ + { + "name": "endmove", + "password": "1f82407cace28cd7d97d23f82e8235d9da97575d033a12334fc71d3517f6a90fa04af829df3c722c38d3b68842e4ca2b", + "aes_key": "p0G+iViPp656O6aMKgcXSDT/e9/00wQH/ztUWf4tyr4=", + "passwordSalt": "ItYiXkwPa84Gwb6dGHQvXQ==", + "files": [ + { + "name": "HELMo.png", + "fileNameSalt": "tadvzRunAGiu0Z059eBPLQ==", + "size": 130146, + "iv": "26s0BqNqVSbzN1lASkUzgQ==", + "storage": [ + "lightcontainerSB01" + ] + }, + { + "name": "apache2.conf", + "fileNameSalt": "C5GNkws8l2HrhIdF7gmG6w==", + "size": 12648, + "iv": "hQx69qQj1ynaxZZ9wAxpbA==", + "storage": [ + "lightcontainerSB01" + ] + } + ] + }, + { + "name": "aaaaa", + "password": "5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617", + "aes_key": "qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=", + "passwordSalt": "Ns8Al6DpqPsIDlCSRBVTEg==", + "files": [ + { + "name": "ca.crt", + "fileNameSalt": "Mjo7iQeEl2PYX1RDUZbSlQ==", + "size": 4207, + "iv": "uALI+Feo1lIg1lBxbCMwIQ==", + "storage": [ + "lightcontainerSB01" + ] + }, + { + "name": "main.py", + "fileNameSalt": "YRwnBiXINCJ+zyxwADgNRQ==", + "size": 854, + "iv": "9LXrJFtcgU4DeUBghc4Dgw==", + "storage": [ + "lightcontainerSB01" + ] + } + ] + } + ] +} \ No newline at end of file