reworked session handler to non-singleton

~10 min work
This commit is contained in:
Benedikt Galbavy 2024-01-21 00:06:44 +01:00
parent 9b1448edd8
commit 6da608f90b
7 changed files with 57 additions and 42 deletions

View File

@ -1,5 +1,6 @@
package at.nanopenguin.mtcg; package at.nanopenguin.mtcg;
import at.nanopenguin.mtcg.application.SessionHandler;
import at.nanopenguin.mtcg.application.service.*; import at.nanopenguin.mtcg.application.service.*;
import at.nanopenguin.mtcg.http.HttpMethod; import at.nanopenguin.mtcg.http.HttpMethod;
import at.nanopenguin.mtcg.http.Router; import at.nanopenguin.mtcg.http.Router;
@ -10,33 +11,34 @@ import java.io.IOException;
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
Router router = new Router(); Router router = new Router();
SessionHandler sessionHandler = new SessionHandler();
router.addRoute(HttpMethod.GET, "/test/{var}/service", new TestService(), new int[]{2}); router.addRoute(HttpMethod.GET, "/test/{var}/service", new TestService(), new int[]{2});
/* users */ /* users */
router.addRoute(HttpMethod.POST, "/users", new UserService(), new int[]{}); router.addRoute(HttpMethod.POST, "/users", new UserService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.GET, "/users/{username}", new UserService(), new int[]{2}); router.addRoute(HttpMethod.GET, "/users/{username}", new UserService(sessionHandler), new int[]{2});
router.addRoute(HttpMethod.PUT, "/users/{username}", new UserService(), new int[]{2}); router.addRoute(HttpMethod.PUT, "/users/{username}", new UserService(sessionHandler), new int[]{2});
router.addRoute(HttpMethod.POST, "/sessions", new UserService(), new int[]{}); router.addRoute(HttpMethod.POST, "/sessions", new UserService(sessionHandler), new int[]{});
/* packages */ /* packages */
router.addRoute(HttpMethod.POST, "/packages", new PackagesService(), new int[]{}); router.addRoute(HttpMethod.POST, "/packages", new PackagesService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.POST, "/transactions/packages", new PackagesService(), new int[]{}); router.addRoute(HttpMethod.POST, "/transactions/packages", new PackagesService(sessionHandler), new int[]{});
/* cards */ /* cards */
router.addRoute(HttpMethod.GET, "/cards", new CardsService(), new int[]{}); router.addRoute(HttpMethod.GET, "/cards", new CardsService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.GET, "/deck", new CardsService(), new int[]{}); router.addRoute(HttpMethod.GET, "/deck", new CardsService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.PUT, "/deck", new CardsService(), new int[]{}); router.addRoute(HttpMethod.PUT, "/deck", new CardsService(sessionHandler), new int[]{});
/* game */ /* game */
router.addRoute(HttpMethod.GET, "/stats", new GameService(), new int[]{}); router.addRoute(HttpMethod.GET, "/stats", new GameService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.GET, "/scoreboard", new GameService(), new int[]{}); router.addRoute(HttpMethod.GET, "/scoreboard", new GameService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.POST, "/battles", new GameService(), new int[]{}); router.addRoute(HttpMethod.POST, "/battles", new GameService(sessionHandler), new int[]{});
/* trading */ /* trading */
router.addRoute(HttpMethod.GET, "/tradings", new TradingService(), new int[]{}); router.addRoute(HttpMethod.GET, "/tradings", new TradingService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.POST, "/tradings", new TradingService(), new int[]{}); router.addRoute(HttpMethod.POST, "/tradings", new TradingService(sessionHandler), new int[]{});
router.addRoute(HttpMethod.DELETE, "/tradings/{tradingDealId}", new TradingService(), new int[]{2}); router.addRoute(HttpMethod.DELETE, "/tradings/{tradingDealId}", new TradingService(sessionHandler), new int[]{2});
router.addRoute(HttpMethod.POST, "/tradings/{tradingDealId}", new TradingService(), new int[]{2}); router.addRoute(HttpMethod.POST, "/tradings/{tradingDealId}", new TradingService(sessionHandler), new int[]{2});
Server server = new Server(10001, 10, router); Server server = new Server(10001, 10, router);
server.start(); server.start();

View File

@ -12,21 +12,8 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
public final class SessionHandler { public final class SessionHandler {
private static SessionHandler INSTANCE;
private final Map<UUID, UserInfo> sessions = new HashMap<>(); private final Map<UUID, UserInfo> sessions = new HashMap<>();
private SessionHandler() {
}
public static SessionHandler getInstance() {
if (INSTANCE == null) {
INSTANCE = new SessionHandler();
}
return INSTANCE;
}
public synchronized UUID login(UserCredentials userCredentials) throws SQLException { // avoid multiple logins of same user public synchronized UUID login(UserCredentials userCredentials) throws SQLException { // avoid multiple logins of same user
val result = DbQuery.builder() val result = DbQuery.builder()

View File

@ -19,14 +19,19 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class CardsService implements Service { public class CardsService implements Service {
private final SessionHandler sessionHandler;
public CardsService(SessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
}
@Override @Override
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException { public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException {
UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")); UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
if (SessionHandler.getInstance().verifyUUID(authToken) != TokenValidity.VALID) if (this.sessionHandler.verifyUUID(authToken) != TokenValidity.VALID)
return new Response(HttpStatus.UNAUTHORIZED); return new Response(HttpStatus.UNAUTHORIZED);
UUID userUuid = SessionHandler.getInstance().userUuidFromToken(authToken); UUID userUuid = this.sessionHandler.userUuidFromToken(authToken);
if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) { if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) {
val result = UserCards.get(userUuid, false); val result = UserCards.get(userUuid, false);

View File

@ -12,14 +12,19 @@ import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
public class GameService implements Service { public class GameService implements Service {
private final SessionHandler sessionHandler;
public GameService(SessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
}
@Override @Override
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException { public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException {
UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")); UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
if (SessionHandler.getInstance().verifyUUID(authToken) != TokenValidity.VALID) if (this.sessionHandler.verifyUUID(authToken) != TokenValidity.VALID)
return new Response(HttpStatus.UNAUTHORIZED); return new Response(HttpStatus.UNAUTHORIZED);
UUID userUuid = SessionHandler.getInstance().userUuidFromToken(authToken); UUID userUuid = this.sessionHandler.userUuidFromToken(authToken);
if (request.getPath().split("/")[1].equals("stats") && request.getMethod() == HttpMethod.GET) { if (request.getPath().split("/")[1].equals("stats") && request.getMethod() == HttpMethod.GET) {
return new Response(HttpStatus.OK, new ObjectMapper().writeValueAsString(User.getStats(userUuid))); return new Response(HttpStatus.OK, new ObjectMapper().writeValueAsString(User.getStats(userUuid)));

View File

@ -20,13 +20,18 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class PackagesService implements Service { public class PackagesService implements Service {
private final SessionHandler sessionHandler;
public PackagesService(SessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
}
@Override @Override
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException { public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException {
UUID token = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")); UUID token = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
if (request.getPath().split("/")[1].equals("packages") && request.getMethod() == HttpMethod.POST) { if (request.getPath().split("/")[1].equals("packages") && request.getMethod() == HttpMethod.POST) {
return switch (SessionHandler.getInstance().verifyUUID(token, true)) { return switch (this.sessionHandler.verifyUUID(token, true)) {
case MISSING, INVALID -> new Response(HttpStatus.UNAUTHORIZED); case MISSING, INVALID -> new Response(HttpStatus.UNAUTHORIZED);
case FORBIDDEN -> new Response(HttpStatus.FORBIDDEN); case FORBIDDEN -> new Response(HttpStatus.FORBIDDEN);
case VALID -> new Response( case VALID -> new Response(
@ -37,12 +42,12 @@ public class PackagesService implements Service {
} }
if (String.join("/", Arrays.copyOfRange(request.getPath().split("/"), 1, 3)).equals("transactions/packages") && request.getMethod() == HttpMethod.POST) { if (String.join("/", Arrays.copyOfRange(request.getPath().split("/"), 1, 3)).equals("transactions/packages") && request.getMethod() == HttpMethod.POST) {
if (SessionHandler.getInstance().verifyUUID(token) != TokenValidity.VALID) return new Response(HttpStatus.UNAUTHORIZED); if (this.sessionHandler.verifyUUID(token) != TokenValidity.VALID) return new Response(HttpStatus.UNAUTHORIZED);
val result = Package.addToUser(SessionHandler.getInstance().userUuidFromToken(token)); val result = Package.addToUser(this.sessionHandler.userUuidFromToken(token));
if (result.left() == PurchaseStatus.SUCCESS) { if (result.left() == PurchaseStatus.SUCCESS) {
return new Response(HttpStatus.OK, "application/json", new ObjectMapper().writeValueAsString(result.right())); return new Response(HttpStatus.OK, "application/json", new ObjectMapper().writeValueAsString(result.right()));
} }
return new Response(switch (Package.addToUser(SessionHandler.getInstance().userUuidFromToken(token)).left()) { return new Response(switch (Package.addToUser(this.sessionHandler.userUuidFromToken(token)).left()) {
case NO_PACKAGE_AVAILABLE -> HttpStatus.NOT_FOUND; case NO_PACKAGE_AVAILABLE -> HttpStatus.NOT_FOUND;
case NOT_ENOUGH_MONEY -> HttpStatus.FORBIDDEN; case NOT_ENOUGH_MONEY -> HttpStatus.FORBIDDEN;
default -> HttpStatus.INTERNAL; default -> HttpStatus.INTERNAL;

View File

@ -15,13 +15,19 @@ import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
public class TradingService implements Service { public class TradingService implements Service {
private final SessionHandler sessionHandler;
public TradingService(SessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
}
@Override @Override
public Response handleRequest(HttpRequest request) throws JsonProcessingException, ArrayIndexOutOfBoundsException, SQLException { public Response handleRequest(HttpRequest request) throws JsonProcessingException, ArrayIndexOutOfBoundsException, SQLException {
UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")); UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
if (SessionHandler.getInstance().verifyUUID(authToken) != TokenValidity.VALID) if (this.sessionHandler.verifyUUID(authToken) != TokenValidity.VALID)
return new Response(HttpStatus.UNAUTHORIZED); return new Response(HttpStatus.UNAUTHORIZED);
UUID userUuid = SessionHandler.getInstance().userUuidFromToken(authToken); UUID userUuid = this.sessionHandler.userUuidFromToken(authToken);
if (request.getPath().split("/")[1].equals("tradings")) { if (request.getPath().split("/")[1].equals("tradings")) {
return switch (request.getMethod()) { return switch (request.getMethod()) {

View File

@ -18,12 +18,17 @@ import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
public class UserService implements Service { public class UserService implements Service {
private final SessionHandler sessionHandler;
public UserService(SessionHandler sessionHandler) {
this.sessionHandler = sessionHandler;
}
@Override @Override
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException { public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException {
if (request.getPath().split("/")[1].equals("sessions") && request.getMethod() == HttpMethod.POST) { if (request.getPath().split("/")[1].equals("sessions") && request.getMethod() == HttpMethod.POST) {
// login // login
UUID uuid = SessionHandler.getInstance().login(new ObjectMapper().readValue(request.getBody(), UserCredentials.class)); UUID uuid = this.sessionHandler.login(new ObjectMapper().readValue(request.getBody(), UserCredentials.class));
return uuid != null ? return uuid != null ?
new Response(HttpStatus.OK, "application/json", uuid.toString()) : new Response(HttpStatus.OK, "application/json", uuid.toString()) :
new Response(HttpStatus.UNAUTHORIZED); new Response(HttpStatus.UNAUTHORIZED);
@ -33,7 +38,7 @@ public class UserService implements Service {
return switch (request.getMethod()) { return switch (request.getMethod()) {
case GET -> { case GET -> {
String username = request.getPath().split("/")[2]; String username = request.getPath().split("/")[2];
if (SessionHandler.getInstance().verifyUUID(SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")), username, true) != TokenValidity.VALID) if (this.sessionHandler.verifyUUID(SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")), username, true) != TokenValidity.VALID)
yield new Response(HttpStatus.UNAUTHORIZED); yield new Response(HttpStatus.UNAUTHORIZED);
val userData = User.retrieve(username); val userData = User.retrieve(username);
yield userData != null ? yield userData != null ?
@ -47,7 +52,7 @@ public class UserService implements Service {
case PUT -> { case PUT -> {
String username = request.getPath().split("/")[2]; String username = request.getPath().split("/")[2];
UserData userData = new ObjectMapper().readValue(request.getBody(), UserData.class); UserData userData = new ObjectMapper().readValue(request.getBody(), UserData.class);
if (SessionHandler.getInstance().verifyUUID(SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")), username, true) != TokenValidity.VALID) if (this.sessionHandler.verifyUUID(SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization")), username, true) != TokenValidity.VALID)
yield new Response(HttpStatus.UNAUTHORIZED); yield new Response(HttpStatus.UNAUTHORIZED);
yield User.update(username, userData) ? new Response(HttpStatus.OK) : new Response(HttpStatus.NOT_FOUND); yield User.update(username, userData) ? new Response(HttpStatus.OK) : new Response(HttpStatus.NOT_FOUND);
} }