mirror of
https://github.com/klmp200/PQT_Gestionnaire_vente_stock.git
synced 2024-11-22 08:13:20 +00:00
[VRAC] Corrections de bug #1/?
Bug détectés restants : - MainFrame pas mise à jour avec le compte utilisateur connecté lorsqu'on switch dessus depuis la StartFrame - Le serveur renvoie REFUSED_QUERY lorsqu'on tente de se déconnecter
This commit is contained in:
parent
d697c1b123
commit
aad90bb989
@ -58,9 +58,12 @@ public class Main extends Application{
|
||||
}
|
||||
|
||||
private IStartupFrameModelListener getStartupFrameListener(Stage primaryStage, Scene sceneToDisplay){
|
||||
return () -> trySwitchScene(primaryStage, sceneToDisplay, true);
|
||||
return () -> {
|
||||
Platform.runLater(()->trySwitchScene(primaryStage, sceneToDisplay, true));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private IMainFrameModelListener getMainFrameListener(Stage primaryStage, Scene sceneToDisplay){
|
||||
return () -> trySwitchScene(primaryStage, sceneToDisplay, false);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class StartupFrameController implements IStartupFrameModelListener {
|
||||
view.getAccountUsernameTextFieldContent(),
|
||||
view.getAccountPasswordTextFieldContent()
|
||||
);
|
||||
}catch(NullPointerException | IllegalArgumentException e){
|
||||
}catch(Exception e){
|
||||
view.displayError(GUIStringTool.getExceptionFormatter().render(e));
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.IStartupProcedureEventFirerer;
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.IStartupProcedureListener;
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.SimpleStartupProcedureEventFirerer;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.account.listeners.AccountListenerAdapter;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
@ -22,6 +23,7 @@ class StartupProcedureHandler {
|
||||
StartupProcedureHandler(NetworkService networkService, AccountService accountService) {
|
||||
this.networkService = networkService;
|
||||
this.accountService = accountService;
|
||||
firerer = new SimpleStartupProcedureEventFirerer();
|
||||
}
|
||||
|
||||
StartupProcedureHandler init(String host, Integer port, String username, String password){
|
||||
@ -39,13 +41,13 @@ class StartupProcedureHandler {
|
||||
|
||||
private void testConnection(){
|
||||
networkService.addListener(getPingListener());
|
||||
networkService.setActiveServer(host, port);
|
||||
networkService.sendPQTPing(host, port);
|
||||
}
|
||||
|
||||
private void useRequestedServer(){
|
||||
//Server found
|
||||
firerer.fireServerFoundEvent(host, port);
|
||||
networkService.setActiveServer(host, port);
|
||||
accountService.addListener(getUpdateAccountListListener());
|
||||
accountService.refreshAccounts();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.pqt.client.module.connection.senders;
|
||||
|
||||
import com.pqt.client.module.connection.listeners.IConnectionListener;
|
||||
import com.sun.javafx.binding.StringFormatter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
@ -14,7 +15,10 @@ public class HttpTextSender implements ITextSender{
|
||||
@Override
|
||||
public void send(String url, String text, IConnectionListener listener) {
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
|
||||
String trueURL = String.format("http://%s?message=%s", url, text);
|
||||
|
||||
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(trueURL).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
con.setConnectTimeout(5000);
|
||||
|
@ -73,7 +73,9 @@ public class NetworkService {
|
||||
}
|
||||
|
||||
public void setActiveServer(String host, Integer port){
|
||||
connectionService.setServerUrl(String.format("%s:%s", host, port));
|
||||
//TODO changer le nom de context de la webapp
|
||||
String webAppContext = "pqt-server";
|
||||
connectionService.setServerUrl(String.format("%s:%s/%s", host, port, webAppContext));
|
||||
}
|
||||
|
||||
private void sendConfigRequest(String host, Integer port){
|
||||
|
@ -4,6 +4,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -20,13 +21,55 @@ public class GSonMessageToolFactory implements IMessageToolFactory {
|
||||
return (obj)->gson.toJson(obj);
|
||||
}
|
||||
public <T> IObjectParser<T> getObjectParser(Class<T> clazz){
|
||||
return (str)->gson.fromJson(str, clazz);
|
||||
return (str)->gson.fromJson(str, new Element<>(clazz));
|
||||
}
|
||||
public <T> IObjectFormatter<List<T>> getListFormatter(Class<T> clazz){
|
||||
return (obj)->gson.toJson(obj);
|
||||
}
|
||||
public <T> IObjectParser<List<T>> getListParser(Class<T> clazz){
|
||||
Type listType = new TypeToken<ArrayList<T>>(){}.getType();
|
||||
return (str)->gson.fromJson(str, listType);
|
||||
//Type listType = new TypeToken<ArrayList<T>>(){}.getType();
|
||||
return (str)->gson.fromJson(str, new ListWithElements<>(clazz));
|
||||
}
|
||||
|
||||
private class Element<T> implements ParameterizedType {
|
||||
|
||||
private Class<T> cl;
|
||||
|
||||
public Element(Class<T> cl) {
|
||||
this.cl = cl;
|
||||
}
|
||||
|
||||
public Type[] getActualTypeArguments() {
|
||||
return new Type[] {cl};
|
||||
}
|
||||
|
||||
public Type getRawType() {
|
||||
return cl;
|
||||
}
|
||||
|
||||
public Type getOwnerType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ListWithElements<T> implements ParameterizedType {
|
||||
|
||||
private Class<T> elementsClass;
|
||||
|
||||
public ListWithElements(Class<T> elementsClass) {
|
||||
this.elementsClass = elementsClass;
|
||||
}
|
||||
|
||||
public Type[] getActualTypeArguments() {
|
||||
return new Type[] {elementsClass};
|
||||
}
|
||||
|
||||
public Type getRawType() {
|
||||
return List.class;
|
||||
}
|
||||
|
||||
public Type getOwnerType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Workspace/server/src/main/WEB-INF/web.xml
Normal file
11
Workspace/server/src/main/WEB-INF/web.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE web-app
|
||||
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
|
||||
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
|
||||
|
||||
<web-app>
|
||||
<context-param>
|
||||
<param-name>res-file.location</param-name>
|
||||
<param-value>G:\temp\</param-value>
|
||||
</context-param>
|
||||
</web-app>
|
@ -5,6 +5,7 @@ import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import com.pqt.server.tools.io.ISerialFileManager;
|
||||
import com.pqt.server.tools.io.SimpleSerialFileManagerFactory;
|
||||
import com.pqt.server.tools.security.IHashTool;
|
||||
import com.pqt.server.tools.security.RandomString;
|
||||
import com.pqt.server.tools.security.SHA256HashTool;
|
||||
|
||||
import java.util.*;
|
||||
@ -22,19 +23,22 @@ import java.util.stream.Collectors;
|
||||
* Cette classe manipule les mot de passe sous forme chiffrée via un système de hash (SHA-256) + salt, et ne fait pas
|
||||
* persister les mots de passes non-chiffrées. Les noms d'utilisateurs sont stockés sans chiffrage.
|
||||
*/
|
||||
class FileAccountDao implements IAccountDao {
|
||||
public class FileAccountDao implements IAccountDao {
|
||||
|
||||
private static final String ACCOUNT_FILE_NAME = "acc.pqt";
|
||||
//TODO to modify
|
||||
private static final String ACCOUNT_FILE_NAME = "G:\\temp\\acc.pqt";
|
||||
|
||||
private Set<AccountEntry> accountEntries;
|
||||
private Set<AccountEntry> connectedAccount;
|
||||
private IHashTool hashTool;
|
||||
private RandomString randomString;
|
||||
private ISerialFileManager<AccountEntry> fileManager;
|
||||
|
||||
FileAccountDao() {
|
||||
public FileAccountDao() {
|
||||
accountEntries = new HashSet<>();
|
||||
connectedAccount = new HashSet<>();
|
||||
hashTool = new SHA256HashTool();
|
||||
randomString = new RandomString(10);
|
||||
fileManager = SimpleSerialFileManagerFactory.getFileManager(AccountEntry.class, ACCOUNT_FILE_NAME);
|
||||
loadFromFile();
|
||||
}
|
||||
@ -96,7 +100,7 @@ class FileAccountDao implements IAccountDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Passe un comtpe connecté dans l'état déconnecté. N'effectue le changement que si un compte connecté correspond
|
||||
* Passe un compte connecté dans l'état déconnecté. N'effectue le changement que si un compte connecté correspond
|
||||
* aux données fournies.
|
||||
* @param account données à utiliser pour efffectuer la correspondance avec un compte
|
||||
* @return {@code true} si le changement d'état a eu lieu, {@code false sinon}
|
||||
@ -134,6 +138,18 @@ class FileAccountDao implements IAccountDao {
|
||||
fileManager.saveSetToFile(accountEntries);
|
||||
}
|
||||
|
||||
public boolean addAccount(Account account){
|
||||
if(accountEntries.stream().filter(accountEntry -> accountEntry.getUsername().equals(account.getUsername())).count()==0) {
|
||||
String salt = randomString.nextString();
|
||||
String passwordHash = hashTool.hashAndSalt(account.getPassword(), salt);
|
||||
accountEntries.add(new AccountEntry(account.getUsername(), passwordHash, salt, account.getPermissionLevel()));
|
||||
saveToFile();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge les données des comptes depuis le fichier de sauvegarde.
|
||||
* <p/>
|
||||
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||
*
|
||||
* @author Guillaume "Cess" Prost
|
||||
*/
|
||||
interface IAccountDao {
|
||||
public interface IAccountDao {
|
||||
|
||||
/**
|
||||
* @see AccountService#isAccountConnected(Account)
|
||||
@ -59,4 +59,14 @@ interface IAccountDao {
|
||||
* de données.
|
||||
*/
|
||||
List<Account> getAccountList();
|
||||
|
||||
/**
|
||||
* Ajoute un objet {@link Account} dans la collection de comptes utilisateurs.
|
||||
* <p/>
|
||||
* 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.
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
boolean addAccount(Account account);
|
||||
}
|
||||
|
@ -19,14 +19,15 @@ import java.util.*;
|
||||
*/
|
||||
public class FileStockDao implements IStockDao {
|
||||
|
||||
private static final String STOCK_FILE_NAME = "stock.pqt";
|
||||
//TODO to modify
|
||||
private static final String STOCK_FILE_NAME = "G:\\temp\\stock.pqt";
|
||||
private ISerialFileManager<Product> fileManager;
|
||||
private long nextProductId;
|
||||
private Random random;
|
||||
|
||||
private Map<Long, Product> products;
|
||||
|
||||
FileStockDao() {
|
||||
public FileStockDao() {
|
||||
random = new Random();
|
||||
fileManager = SimpleSerialFileManagerFactory.getFileManager(Product.class, STOCK_FILE_NAME);
|
||||
loadFromFile();
|
||||
|
@ -28,10 +28,16 @@ public class QueryServlet extends HttpServlet {
|
||||
IMessageToolFactory messageToolFactory = new GSonMessageToolFactory();
|
||||
IMessageHandler msgHandler = new SimpleMessageHandler();
|
||||
|
||||
if (request.getParameter("message") != null) {
|
||||
Message resp = msgHandler.handleMessage(messageToolFactory.getObjectParser(Message.class).parse(request.getParameter("message")));
|
||||
if (request.getQueryString() != null && !request.getQueryString().isEmpty() && request.getParameter("message")!=null) {
|
||||
try {
|
||||
Message resp = msgHandler.handleMessage(messageToolFactory.getObjectParser(Message.class).parse(request.getParameter("message")));
|
||||
|
||||
response.getWriter().write(messageToolFactory.getObjectFormatter(Message.class).format(resp));
|
||||
response.getWriter().write(messageToolFactory.getObjectFormatter(Message.class).format(resp));
|
||||
}catch(Exception e){
|
||||
response.getWriter().write(String.format("%s : %s", e.getClass().getName(), e.getMessage()));
|
||||
}
|
||||
}else{
|
||||
response.getWriter().write("Query message was not correctly made : "+request.getQueryString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class FileUtil {
|
||||
* @throws IOException if any IOException happend during this method's execution.
|
||||
*/
|
||||
public static boolean createFileIfNotExist(Path filePath) throws IOException {
|
||||
if(FileUtil.exist(filePath)){
|
||||
if(!FileUtil.exist(filePath)){
|
||||
Files.createFile(filePath);
|
||||
return true;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class SimpleSerialFileManager<T> implements ISerialFileManager<T> {
|
||||
}catch(IOException | ClassNotFoundException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -52,7 +52,7 @@ public class SimpleSerialFileManager<T> implements ISerialFileManager<T> {
|
||||
}catch(IOException | ClassNotFoundException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
private void fillCollection(Collection<T> collection) throws IOException, ClassNotFoundException {
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.pqt.server.tools.io;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class SimpleSerialFileManagerFactory {
|
||||
protected SimpleSerialFileManagerFactory(){}
|
||||
|
||||
public static <T> ISerialFileManager<T> getFileManager(Class<T> clazz, String filePath){
|
||||
return new SimpleSerialFileManager<>(filePath, clazz);
|
||||
return SimpleSerialFileManagerFactory.getFileManager(clazz, Paths.get(filePath));
|
||||
}
|
||||
|
||||
public static <T> ISerialFileManager<T> getFileManager(Class<T> clazz, Path filePath){
|
||||
|
@ -0,0 +1,62 @@
|
||||
package com.pqt.server.tools.security;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomString {
|
||||
|
||||
/**
|
||||
* Generate a random string.
|
||||
*/
|
||||
public String nextString() {
|
||||
for (int idx = 0; idx < buf.length; ++idx)
|
||||
buf[idx] = symbols[random.nextInt(symbols.length)];
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
public static final String lower = upper.toLowerCase(Locale.ROOT);
|
||||
|
||||
public static final String digits = "0123456789";
|
||||
|
||||
public static final String alphanum = upper + lower + digits;
|
||||
|
||||
private final Random random;
|
||||
|
||||
private final char[] symbols;
|
||||
|
||||
private final char[] buf;
|
||||
|
||||
public RandomString(int length, Random random, String symbols) {
|
||||
if (length < 1) throw new IllegalArgumentException();
|
||||
if (symbols.length() < 2) throw new IllegalArgumentException();
|
||||
this.random = Objects.requireNonNull(random);
|
||||
this.symbols = symbols.toCharArray();
|
||||
this.buf = new char[length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an alphanumeric string generator.
|
||||
*/
|
||||
public RandomString(int length, Random random) {
|
||||
this(length, random, alphanum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an alphanumeric strings from a secure generator.
|
||||
*/
|
||||
public RandomString(int length) {
|
||||
this(length, new SecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create session identifiers.
|
||||
*/
|
||||
public RandomString() {
|
||||
this(21);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user