diff --git a/Workspace/server/src/main/java/com/pqt/server/controller/SimpleMessageHandler.java b/Workspace/server/src/main/java/com/pqt/server/controller/SimpleMessageHandler.java index 729cff1d..8b6c278d 100644 --- a/Workspace/server/src/main/java/com/pqt/server/controller/SimpleMessageHandler.java +++ b/Workspace/server/src/main/java/com/pqt/server/controller/SimpleMessageHandler.java @@ -12,6 +12,7 @@ import com.pqt.core.entities.sale.LightweightSale; import com.pqt.core.entities.server_config.ServerConfig; import com.pqt.core.entities.user_account.Account; import com.pqt.core.entities.user_account.AccountLevel; +import com.pqt.core.entities.user_account.AccountUpdate; import com.pqt.server.exception.ServerQueryException; import com.pqt.server.module.account.AccountService; import com.pqt.server.module.sale.SaleService; @@ -124,13 +125,24 @@ public class SimpleMessageHandler implements IMessageHandler { List updates = messageToolFactory.getListParser(ProductUpdate.class).parse(message.getField("updates")); stockService.applyUpdateList(updates); return new Message(MessageType.ACK_STOCK_UPDATE, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, null); - }catch (ServerQueryException | NullPointerException e){ + }catch (Exception e){ Map fields = new HashMap<>(); fields.put(header_err_query, e.toString()); return new Message(MessageType.ERROR_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); } }, AccountLevel.MASTER); + manager.supportForConnectedAccounts(MessageType.QUERY_ACCOUNT_UPDATE, (message)->{ + try{ + List updates = messageToolFactory.getListParser(AccountUpdate.class).parse(message.getField("updates")); + accountService.applyUpdateList(updates); + return new Message(MessageType.ACK_ACCOUNT_UPDATE, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, null); + }catch (Exception e){ + Map fields = new HashMap<>(); + fields.put(header_err_query, e.toString()); + return new Message(MessageType.ERROR_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); + } + }, AccountLevel.MASTER); /* Queries without account connection requirements */ diff --git a/Workspace/server/src/main/java/com/pqt/server/module/account/AccountService.java b/Workspace/server/src/main/java/com/pqt/server/module/account/AccountService.java index 432eff9f..372cace3 100644 --- a/Workspace/server/src/main/java/com/pqt/server/module/account/AccountService.java +++ b/Workspace/server/src/main/java/com/pqt/server/module/account/AccountService.java @@ -2,6 +2,7 @@ package com.pqt.server.module.account; import com.pqt.core.entities.user_account.Account; import com.pqt.core.entities.user_account.AccountLevel; +import com.pqt.core.entities.user_account.AccountUpdate; import java.util.List; @@ -117,4 +118,21 @@ public class AccountService { public List getAccountList(){ return dao.getAccountList(); } + + public void applyUpdateList(List updates) { + updates.stream() + .filter(update-> + (update.getOldVersion()!=null && dao.isAccountRegistered(update.getOldVersion())) + || update.getNewVersion()!=null) + .forEach(update->{ + if(update.getNewVersion()==null){ + if(!dao.isAccountConnected(update.getOldVersion())) + dao.removeAccount(update.getOldVersion()); + }else if(update.getOldVersion()==null){ + dao.addAccount(update.getNewVersion()); + }else{ + dao.modifyAccount(update.getOldVersion(), update.getNewVersion()); + } + }); + } } diff --git a/Workspace/server/src/main/java/com/pqt/server/module/account/FileAccountDao.java b/Workspace/server/src/main/java/com/pqt/server/module/account/FileAccountDao.java index 69a2aa77..8c27c88b 100644 --- a/Workspace/server/src/main/java/com/pqt/server/module/account/FileAccountDao.java +++ b/Workspace/server/src/main/java/com/pqt/server/module/account/FileAccountDao.java @@ -103,7 +103,8 @@ public class FileAccountDao implements IAccountDao { String expectedPasswordHash = entry.getPasswordHash(); String salt = entry.getSalt(); - if(expectedUsername.equals(account.getUsername()) && hashTool.hashAndSalt(account.getPassword(), salt).equals(expectedPasswordHash)){ + if(expectedUsername.equals(account.getUsername()) + && hashTool.hashAndSalt(account.getPassword(), salt).equals(expectedPasswordHash)){ connectedAccount.add(entry); return true; }else @@ -140,7 +141,9 @@ public class FileAccountDao implements IAccountDao { @Override public synchronized List getAccountList() { - return accountEntries.stream().map(accountEntry -> new Account(accountEntry.getUsername(), null, accountEntry.getLevel())).collect(Collectors.toList()); + return accountEntries.stream() + .map(accountEntry -> new Account(accountEntry.getUsername(), null, accountEntry.getLevel())) + .collect(Collectors.toList()); } /** @@ -150,11 +153,14 @@ public class FileAccountDao implements IAccountDao { fileManager.saveSetToFile(accountEntries); } - public boolean addAccount(Account account){ - if(accountEntries.stream().filter(accountEntry -> accountEntry.getUsername().equals(account.getUsername())).count()==0) { + @Override + public synchronized boolean addAccount(Account account){ + if(accountEntries.stream().noneMatch(accountEntry -> accountEntry.getUsername().equals(account.getUsername()))){ String salt = randomString.nextString(); String passwordHash = hashTool.hashAndSalt(account.getPassword(), salt); - accountEntries.add(new AccountEntry(account.getUsername(), passwordHash, salt, account.getPermissionLevel())); + accountEntries.add( + new AccountEntry(account.getUsername(), passwordHash, salt, account.getPermissionLevel()) + ); saveToFile(); return true; }else{ @@ -162,6 +168,33 @@ public class FileAccountDao implements IAccountDao { } } + @Override + public synchronized void removeAccount(Account oldVersion) { + AccountEntry match = lookupMatchingEntry(oldVersion, accountEntries); + if(match!=null && !connectedAccount.contains(match)){ + accountEntries.remove(match); + saveToFile(); + } + } + + @Override + public synchronized void modifyAccount(Account oldVersion, Account newVersion) { + AccountEntry match = lookupMatchingEntry(oldVersion, accountEntries); + if(match!=null && oldVersion.getUsername().equals(newVersion.getUsername())){ + boolean toReconnect = connectedAccount.remove(match); + accountEntries.remove(match); + + String salt = randomString.nextString(); + String passwordHash = hashTool.hashAndSalt(newVersion.getPassword(), salt); + AccountEntry newEntry = + new AccountEntry(oldVersion.getUsername(), passwordHash, salt, newVersion.getPermissionLevel()); + accountEntries.add(newEntry); + if(toReconnect) + connectedAccount.add(newEntry); + saveToFile(); + } + } + /** * Charge les données des comptes depuis le fichier de sauvegarde. *

diff --git a/Workspace/server/src/main/java/com/pqt/server/module/account/IAccountDao.java b/Workspace/server/src/main/java/com/pqt/server/module/account/IAccountDao.java index 0d53ee58..03185abe 100644 --- a/Workspace/server/src/main/java/com/pqt/server/module/account/IAccountDao.java +++ b/Workspace/server/src/main/java/com/pqt/server/module/account/IAccountDao.java @@ -63,10 +63,31 @@ public interface IAccountDao { /** * Ajoute un objet {@link Account} dans la collection de comptes utilisateurs. *

- * Les implémentations doivent en outre effectuer une vérification pour s'assurer que le compte à rajouter ne pas - * un nom d'utilisateur qui existe déjà. Dans ce cas de figure, l'ajout du nouveau compte doit échouer. + * Les implémentations doivent en outre effectuer une vérification pour s'assurer que le compte à rajouter ne soit + * pas un nom d'utilisateur qui existe déjà. Dans ce cas de figure, l'ajout du nouveau compte doit échouer. * @param account * @return */ boolean addAccount(Account account); + + /** + * Retire un objet {@link Account} dans la collection de comptes utilisateurs. + *

+ * Les implémentations doivent en outre effectuer une vérification pour s'assurer que le compte à retirer ne soit + * pas un compte utilisateur actuellement connecté. Dans ce cas de figure, l'ajout du nouveau compte doit échouer. + * + * @param oldVersion + */ + void removeAccount(Account oldVersion); + + /** + * Modifie un objet {@link Account} {@code oldVersion} en remplaçant ses attributs par ceux de {@code newVersion}. + *

+ * Les implémentations doivent s'assurer que le nouveau nom ne soit pas un nom déjà existant dans la base de données. + * Dans un tel cas de figure, la modification doit échouer et doit laisser {@code oldVersion} inchangé. + * + * @param oldVersion + * @param newVersion + */ + void modifyAccount(Account oldVersion, Account newVersion); }