From a77e0f9396b5f022db73e6d421efc6466e7dd464 Mon Sep 17 00:00:00 2001 From: maciejrusek Date: Wed, 15 Apr 2026 21:37:13 +0200 Subject: [PATCH] Added controllers and simple management --- pom.xml | 6 ++ src/main/java/auth/PasswordService.java | 17 ++++ src/main/java/server/ChatServer.java | 115 ++++++++++++++++++------ src/main/java/server/Controller.java | 14 --- src/main/java/server/Main.java | 19 +++- src/main/java/server/Service.java | 4 - src/main/java/user/UserDao.java | 10 +-- src/test/java/ChatServerTest.java | 16 +++- 8 files changed, 146 insertions(+), 55 deletions(-) create mode 100644 src/main/java/auth/PasswordService.java delete mode 100644 src/main/java/server/Controller.java delete mode 100644 src/main/java/server/Service.java diff --git a/pom.xml b/pom.xml index f8de71c..9b5d72a 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,12 @@ test + + org.mindrot + jbcrypt + 0.4 + + org.xerial diff --git a/src/main/java/auth/PasswordService.java b/src/main/java/auth/PasswordService.java new file mode 100644 index 0000000..66e82b7 --- /dev/null +++ b/src/main/java/auth/PasswordService.java @@ -0,0 +1,17 @@ +package auth; + +import org.mindrot.jbcrypt.BCrypt; + +public class PasswordService { + + public static String hashPassword(String password) { + String salt = BCrypt.gensalt(12); + + return BCrypt.hashpw(password, salt); + } + + public static Boolean comparePassword(String password, String hashPassword) { + return BCrypt.checkpw(password, hashPassword); + } + +} diff --git a/src/main/java/server/ChatServer.java b/src/main/java/server/ChatServer.java index 0ccb35d..5613b5c 100644 --- a/src/main/java/server/ChatServer.java +++ b/src/main/java/server/ChatServer.java @@ -1,8 +1,10 @@ package server; +import auth.PasswordService; import user.User; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import user.UserController; import java.io.BufferedReader; import java.io.IOException; @@ -11,30 +13,26 @@ import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; - +import java.util.Arrays; +import java.util.Optional; public class ChatServer implements Runnable { - private int port = 9000; - private ServerSocket serverSocket; - private ArrayList clientSockets = new ArrayList(); - private static final Logger logger = LogManager.getLogger(); - public ChatServer() { - } + private int port = 9000; + private ServerSocket serverSocket; + private UserController controller; + private ArrayList clientSockets = new ArrayList(); - public ChatServer(int port) { + public ChatServer(int port, UserController userController) { this.port = port; + this.controller = userController; } public ServerSocket getServerSocket() { return serverSocket; } - private User getOrCreateUser(String username) { - return new User(username); - } - private void SendMessage(User user, String msg) { try { for (Socket client : clientSockets) { @@ -49,43 +47,104 @@ public class ChatServer implements Runnable { private void handleClient(Socket socket) { try { - String msg; User user = null; PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - out.println("Login: /login username"); while ((msg = in.readLine()) != null) { - if (user != null) { - SendMessage(user, msg); - } + if (msg.toLowerCase().startsWith("/")) { + ArrayList result = new ArrayList<>(); + String[] data = msg.toLowerCase().replace("/", "").split(" "); + String path = data[0]; + String[] restArray = Arrays.copyOfRange(data, 1, data.length); - if (user == null) { - if (msg.toLowerCase().startsWith("/login")) { - String username = msg.substring(6).strip(); - user = getOrCreateUser(username); - clientSockets.add(socket); - logger.info("client.Client sie połączył"); + switch (path) { + case "login": + if (user != null) { + result.add("You are already logged in"); + break; + } + + if (restArray.length == 2) { + String username = restArray[0]; + String password = restArray[1]; + + Optional userOptional = controller.getUser(username, password); + + if (userOptional.isPresent()) { + user = userOptional.get(); + clientSockets.add(socket); + } else { + result.add("Login failed. Please enter the correct password!"); + break; + } + } else { + result.add("Login failed. Please enter the correct password!"); + } + break; + case "register": + if (user != null) { + result.add("You are already logged in"); + break; + } + + if (restArray.length == 2) { + String username = restArray[0]; + String password = restArray[1]; + + Optional userOptional = controller.createUser(username, password); + + if (userOptional.isPresent()) { + user = userOptional.get(); + clientSockets.add(socket); + } else { + result.add("Register failed. Please enter the correct password!"); + break; + } + + } else { + result.add("Register failed. Please enter the correct password!"); + } + break; + case "logout": + user = null; + clientSockets.remove(socket); + result.add("You have been logged out"); + break; + case "help": + result.add("/login - Login into your account, example: /login Janek Password123"); + result.add("/register - Create an account, example: /register Olek Password321"); + result.add("/logout - logout account"); + break; + case null, default: + result.add("Invalid command!"); + break; + } + + if (result != null) { + result.forEach(out::println); + } + } else { + if (user != null) { + SendMessage(user, msg); + } else { + out.println("Please login or register..."); } } } - } catch (IOException e) { clientSockets.remove(socket); - e.printStackTrace(); + logger.error(e.toString()); } } - @Override public void run() { try { serverSocket = new ServerSocket(port); - logger.error("Test"); - while (true) { Socket clientSocket = serverSocket.accept(); diff --git a/src/main/java/server/Controller.java b/src/main/java/server/Controller.java deleted file mode 100644 index ea09c81..0000000 --- a/src/main/java/server/Controller.java +++ /dev/null @@ -1,14 +0,0 @@ -package server; - -public class Controller { - - public void route(String path) { - - - - } - - - -} - diff --git a/src/main/java/server/Main.java b/src/main/java/server/Main.java index 497c1c9..1e68234 100644 --- a/src/main/java/server/Main.java +++ b/src/main/java/server/Main.java @@ -1,11 +1,24 @@ package server; +import user.UserController; +import user.UserDao; +import user.UserService; + public class Main { - public static void main(String[] args) { - ChatServer chatServer = new ChatServer(9000); + public static UserController init() { + UserDao userDao = new UserDao(); + UserService userService = new UserService(userDao); + UserController userController = new UserController(userService); - Thread serverThread = new Thread(chatServer); + return userController; + } + + public static void main(String[] args) { + UserController userController = init(); + + ChatServer chatServer = new ChatServer(9000, userController); + Thread serverThread = new Thread(chatServer, "chat-server"); serverThread.start(); } diff --git a/src/main/java/server/Service.java b/src/main/java/server/Service.java deleted file mode 100644 index 6e6590c..0000000 --- a/src/main/java/server/Service.java +++ /dev/null @@ -1,4 +0,0 @@ -package server; - -public class Service { -} diff --git a/src/main/java/user/UserDao.java b/src/main/java/user/UserDao.java index 02f02ce..b016179 100644 --- a/src/main/java/user/UserDao.java +++ b/src/main/java/user/UserDao.java @@ -1,10 +1,11 @@ package user; +import auth.PasswordService; + import java.sql.*; import java.util.Optional; public class UserDao { - public static final String DRIVER = "org.sqlite.JDBC"; public static final String DB_URL = "jdbc:sqlite:chat.db"; @@ -57,12 +58,13 @@ public class UserDao { public Optional insertUser(String username, String password) { try { + String hashPassword = PasswordService.hashPassword(password); PreparedStatement preparedStatement = conn.prepareStatement( "INSERT INTO users VALUES (NULL, ?, ?);" ); preparedStatement.setString(1, username); - preparedStatement.setString(2, password); // FIXME, later hash or smth.. + preparedStatement.setString(2, hashPassword); preparedStatement.execute(); User user = new User(username); @@ -82,13 +84,11 @@ public class UserDao { preparedStatement.setString(1, username); ResultSet result = preparedStatement.executeQuery(); - // FIXME: Hasło tu też ogarnąć String passwordFromDB; - while (result.next()) { passwordFromDB = result.getString("password"); - if (password.equals(passwordFromDB)) { + if (PasswordService.comparePassword(password, passwordFromDB)) { return Optional.of(new User(username)); } else { return Optional.empty(); diff --git a/src/test/java/ChatServerTest.java b/src/test/java/ChatServerTest.java index 11e2ed9..31ea14a 100644 --- a/src/test/java/ChatServerTest.java +++ b/src/test/java/ChatServerTest.java @@ -1,13 +1,27 @@ import server.ChatServer; import org.junit.jupiter.api.Test; +import user.UserController; +import user.UserDao; +import user.UserService; import static org.junit.jupiter.api.Assertions.*; public class ChatServerTest { + public static UserController init() { + UserDao userDao = new UserDao(); + UserService userService = new UserService(userDao); + UserController userController = new UserController(userService); + + return userController; + } + @Test void checkIfServerUp() throws Exception { - ChatServer chatServer = new ChatServer(0); + // Fixme: Powinno sie to odnosić na inną baze danych. + UserController controller = init(); + + ChatServer chatServer = new ChatServer(0, controller); Thread serverThread = new Thread(chatServer); serverThread.start();