Added controllers and simple management

This commit is contained in:
maciejrusek
2026-04-15 21:37:13 +02:00
parent d41b918f59
commit a77e0f9396
8 changed files with 146 additions and 55 deletions

View File

@@ -33,6 +33,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<!-- Server --> <!-- Server -->
<dependency> <dependency>
<groupId>org.xerial</groupId> <groupId>org.xerial</groupId>

View File

@@ -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);
}
}

View File

@@ -1,8 +1,10 @@
package server; package server;
import auth.PasswordService;
import user.User; import user.User;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import user.UserController;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
@@ -11,30 +13,26 @@ import java.io.PrintWriter;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Optional;
public class ChatServer implements Runnable { public class ChatServer implements Runnable {
private int port = 9000;
private ServerSocket serverSocket;
private ArrayList<Socket> clientSockets = new ArrayList<Socket>();
private static final Logger logger = LogManager.getLogger(); private static final Logger logger = LogManager.getLogger();
public ChatServer() { private int port = 9000;
} private ServerSocket serverSocket;
private UserController controller;
private ArrayList<Socket> clientSockets = new ArrayList<Socket>();
public ChatServer(int port) { public ChatServer(int port, UserController userController) {
this.port = port; this.port = port;
this.controller = userController;
} }
public ServerSocket getServerSocket() { public ServerSocket getServerSocket() {
return serverSocket; return serverSocket;
} }
private User getOrCreateUser(String username) {
return new User(username);
}
private void SendMessage(User user, String msg) { private void SendMessage(User user, String msg) {
try { try {
for (Socket client : clientSockets) { for (Socket client : clientSockets) {
@@ -49,43 +47,104 @@ public class ChatServer implements Runnable {
private void handleClient(Socket socket) { private void handleClient(Socket socket) {
try { try {
String msg; String msg;
User user = null; User user = null;
PrintWriter out = new PrintWriter(socket.getOutputStream(), true); PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("Login: /login username");
while ((msg = in.readLine()) != null) { while ((msg = in.readLine()) != null) {
if (user != null) { if (msg.toLowerCase().startsWith("/")) {
SendMessage(user, msg); ArrayList<String> result = new ArrayList<>();
} String[] data = msg.toLowerCase().replace("/", "").split(" ");
String path = data[0];
String[] restArray = Arrays.copyOfRange(data, 1, data.length);
if (user == null) { switch (path) {
if (msg.toLowerCase().startsWith("/login")) { case "login":
String username = msg.substring(6).strip(); if (user != null) {
user = getOrCreateUser(username); result.add("You are already logged in");
clientSockets.add(socket); break;
logger.info("client.Client sie połączył"); }
if (restArray.length == 2) {
String username = restArray[0];
String password = restArray[1];
Optional<User> 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<User> 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) { } catch (IOException e) {
clientSockets.remove(socket); clientSockets.remove(socket);
e.printStackTrace(); logger.error(e.toString());
} }
} }
@Override @Override
public void run() { public void run() {
try { try {
serverSocket = new ServerSocket(port); serverSocket = new ServerSocket(port);
logger.error("Test");
while (true) { while (true) {
Socket clientSocket = serverSocket.accept(); Socket clientSocket = serverSocket.accept();

View File

@@ -1,14 +0,0 @@
package server;
public class Controller {
public void route(String path) {
}
}

View File

@@ -1,11 +1,24 @@
package server; package server;
import user.UserController;
import user.UserDao;
import user.UserService;
public class Main { public class Main {
public static void main(String[] args) { public static UserController init() {
ChatServer chatServer = new ChatServer(9000); 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(); serverThread.start();
} }

View File

@@ -1,4 +0,0 @@
package server;
public class Service {
}

View File

@@ -1,10 +1,11 @@
package user; package user;
import auth.PasswordService;
import java.sql.*; import java.sql.*;
import java.util.Optional; import java.util.Optional;
public class UserDao { public class UserDao {
public static final String DRIVER = "org.sqlite.JDBC"; public static final String DRIVER = "org.sqlite.JDBC";
public static final String DB_URL = "jdbc:sqlite:chat.db"; public static final String DB_URL = "jdbc:sqlite:chat.db";
@@ -57,12 +58,13 @@ public class UserDao {
public Optional<User> insertUser(String username, String password) { public Optional<User> insertUser(String username, String password) {
try { try {
String hashPassword = PasswordService.hashPassword(password);
PreparedStatement preparedStatement = conn.prepareStatement( PreparedStatement preparedStatement = conn.prepareStatement(
"INSERT INTO users VALUES (NULL, ?, ?);" "INSERT INTO users VALUES (NULL, ?, ?);"
); );
preparedStatement.setString(1, username); preparedStatement.setString(1, username);
preparedStatement.setString(2, password); // FIXME, later hash or smth.. preparedStatement.setString(2, hashPassword);
preparedStatement.execute(); preparedStatement.execute();
User user = new User(username); User user = new User(username);
@@ -82,13 +84,11 @@ public class UserDao {
preparedStatement.setString(1, username); preparedStatement.setString(1, username);
ResultSet result = preparedStatement.executeQuery(); ResultSet result = preparedStatement.executeQuery();
// FIXME: Hasło tu też ogarnąć
String passwordFromDB; String passwordFromDB;
while (result.next()) { while (result.next()) {
passwordFromDB = result.getString("password"); passwordFromDB = result.getString("password");
if (password.equals(passwordFromDB)) { if (PasswordService.comparePassword(password, passwordFromDB)) {
return Optional.of(new User(username)); return Optional.of(new User(username));
} else { } else {
return Optional.empty(); return Optional.empty();

View File

@@ -1,13 +1,27 @@
import server.ChatServer; import server.ChatServer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import user.UserController;
import user.UserDao;
import user.UserService;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class ChatServerTest { public class ChatServerTest {
public static UserController init() {
UserDao userDao = new UserDao();
UserService userService = new UserService(userDao);
UserController userController = new UserController(userService);
return userController;
}
@Test @Test
void checkIfServerUp() throws Exception { 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); Thread serverThread = new Thread(chatServer);
serverThread.start(); serverThread.start();