import com.fasterxml.jackson.databind.ObjectMapper; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import java.io.IOException; import java.security.GeneralSecurityException; import java.sql.SQLException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class AccountHandler implements HttpHandler { // Simple in-memory session management private static final Map sessions = new ConcurrentHashMap<>(); private static final String CLIENT_ID = "376204422797-s8f05nn6drmec1cko2h4kg1nk24abgc9.apps.googleusercontent.com"; @Override public void handle(HttpExchange exchange) throws IOException { String path = exchange.getRequestURI().getPath(); String method = exchange.getRequestMethod(); if ("POST".equalsIgnoreCase(method)) { switch (path) { case "/account/register": handleRegister(exchange); break; case "/account/login": handleLogin(exchange); break; case "/account/logout": handleLogout(exchange); break; case "/account/delete": handleDeleteAccount(exchange); break; default: Server.sendResponse(exchange, 404, "Endpoint not found"); } } else if ("GET".equalsIgnoreCase(method) && path.equalsIgnoreCase("/account/session")) { handleSession(exchange); } else { Server.sendResponse(exchange, 405, "Method not allowed"); } } private void handleSession(HttpExchange exchange) throws IOException { String sessionId = getSessionId(exchange); ObjectMapper mapper = new ObjectMapper(); Map response = new HashMap<>(); if (sessionId != null && sessions.containsKey(sessionId)) { response.put("loggedIn", true); response.put("user", sessions.get(sessionId)); try { response.put("isAdmin", DatabaseUtil.isAdmin(sessions.get(sessionId))); } catch (SQLException e) { e.printStackTrace(); response.put("isAdmin", false); } } else { response.put("loggedIn", false); } String jsonResponse = mapper.writeValueAsString(response); Server.sendResponse(exchange, 200, jsonResponse); } private String getSessionId(HttpExchange exchange) { List cookies = exchange.getRequestHeaders().get("Cookie"); if (cookies != null) { for (String cookie : cookies) { if (cookie.contains("sessionId=")) { return cookie.replaceAll("g_state=\\{\"i_l\":0\\}; sessionId=", ""); } } } return null; } private void handleRegister(HttpExchange exchange) throws IOException { String requestBody = new String(exchange.getRequestBody().readAllBytes()); ObjectMapper mapper = new ObjectMapper(); Map formData = mapper.readValue(requestBody, Map.class); String username = formData.get("username"); String email = formData.get("email"); String password = formData.get("password"); try { if (DatabaseUtil.registerUser(username, email, password)) { Server.sendResponse(exchange, 200, "{\"message\": \"Registration successful!\"}"); } else { Server.sendResponse(exchange, 400, "{\"message\": \"Registration failed! User may already exist.\"}"); } } catch (SQLException e) { e.printStackTrace(); Server.sendResponse(exchange, 500, "{\"message\": \"Internal server error\"}"); } } private void handleLogin(HttpExchange exchange) throws IOException { String requestBody = new String(exchange.getRequestBody().readAllBytes()); ObjectMapper mapper = new ObjectMapper(); Map formData = mapper.readValue(requestBody, Map.class); if (formData.containsKey("id_token")) { handleGoogleSignIn(exchange, formData.get("id_token")); } else { handleFormLogin(exchange, formData.get("email"), formData.get("password")); } } private void handleGoogleSignIn(HttpExchange exchange, String idTokenString) throws IOException { HttpTransport transport = new NetHttpTransport(); JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) .setAudience(Collections.singletonList(CLIENT_ID)).build(); try { GoogleIdToken idToken = verifier.verify(idTokenString); if (idToken != null) { GoogleIdToken.Payload payload = idToken.getPayload(); String email = payload.getEmail(); if (DatabaseUtil.userExists(email)) { System.out.println("User exists, logging in"); handleFormLogin(exchange, email, null); } else { System.out.println("User does not exist, creating new user"); String name = (String) payload.get("name"); DatabaseUtil.registerUser(name, email, null); // Password is null for Google login String response = createSession(email); Server.sendResponse(exchange, 200, response); } } else { String response = "{\"message\": \"Invalid ID token\"}"; System.out.println(response); Server.sendResponse(exchange, 401, response); } } catch (SQLException e) { e.printStackTrace(); String response = "{\"message\": \"Database error\"}"; System.out.println(response); Server.sendResponse(exchange, 500, response); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } private void handleFormLogin(HttpExchange exchange, String email, String password) throws IOException { try { if (DatabaseUtil.userExists(email)) { if (DatabaseUtil.authenticateUser(email, password)) { String response = createSession(email); Server.sendResponse(exchange, 200, response); } else { String response = "{\"message\": \"Invalid password\"}"; System.out.println(response); Server.sendResponse(exchange, 401, response); } } else { String response = "{\"message\": \"User does not exist\"}"; System.out.println(response); Server.sendResponse(exchange, 404, response); } } catch (SQLException e) { e.printStackTrace(); String response = "{\"message\": \"Database error: " + e.getMessage() + "\"}"; System.out.println(response); Server.sendResponse(exchange, 500, response); } } private void handleLogout(HttpExchange exchange) throws IOException { String sessionId = getSessionId(exchange); if (sessionId != null && sessions.containsKey(sessionId)) { sessions.remove(sessionId); Server.sendResponse(exchange, 200, "{\"message\": \"Logout successful\"}"); } else { Server.sendResponse(exchange, 401, "{\"message\": \"Not logged in\"}"); } } private void handleDeleteAccount(HttpExchange exchange) throws IOException { String userIdStr = new String(exchange.getRequestBody().readAllBytes()).replaceAll("\"", ""); int userId = Integer.parseInt(userIdStr); Map response = new HashMap<>(); try { boolean success = DatabaseUtil.deleteUser(userId); response.put("success", success); if (!success) { response.put("message", "User not found"); } } catch (SQLException e) { e.printStackTrace(); response.put("success", false); response.put("message", "Database error: " + e.getMessage()); } String jsonResponse = new ObjectMapper().writeValueAsString(response); Server.sendResponse(exchange, 200, jsonResponse); } private String createSession(String email) throws SQLException { String sessionId = UUID.randomUUID().toString(); sessions.put(sessionId, email); boolean isAdmin = DatabaseUtil.isAdmin(email); return "{\"message\": \"" + email + " logged in!\", \"sessionId\": \"" + sessionId + "\", \"isAdmin\": " + isAdmin + "}"; } }