user data get/put && sessions

~2.25h work
This commit is contained in:
Benedikt Galbavy 2024-01-04 19:41:22 +01:00
parent 88f996f5e0
commit 446b01d927
5 changed files with 66 additions and 10 deletions

View File

@ -6,7 +6,6 @@ import at.nanopenguin.mtcg.db.SqlCommand;
import at.nanopenguin.mtcg.db.Table;
import lombok.val;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
@ -14,7 +13,7 @@ import java.util.UUID;
public final class SessionHandler {
private static SessionHandler INSTANCE;
private final Map<UUID, Integer> Sessions = new HashMap<>();
private final Map<UUID, UserInfo> Sessions = new HashMap<>();
private SessionHandler() {
@ -34,19 +33,38 @@ public final class SessionHandler {
.table(Table.USERS)
.column("id")
.column("password")
.column("admin")
.condition("username", userCredentials.username())
.executeQuery();
if (result.isEmpty()) {
// user not found
return null;
}
if (!result.get(0).get("password").equals(userCredentials.password())) {
val row1 = result.get(0);
if (!row1.get("password").equals(userCredentials.password())) {
// wrong password
return null;
}
UUID uuid = UUID.randomUUID();
this.Sessions.put(uuid, (Integer) result.get(0).get("id"));
this.Sessions.put(uuid, new UserInfo((int) row1.get("id"), userCredentials.username(), (boolean) row1.get("admin")));
return uuid;
}
public boolean verifyUUID(UUID uuid) {
return verifyUUID(uuid, false);
}
public boolean verifyUUID(UUID uuid, boolean requireAdmin) {
return Sessions.containsKey(uuid) && (!requireAdmin || Sessions.get(uuid).admin());
}
public boolean verifyUUID(UUID uuid, String username) {
return verifyUUID(uuid, username, false);
}
public boolean verifyUUID(UUID uuid, String username, boolean allowAdmin) {
return Sessions.containsKey(uuid) && (username.equals(Sessions.get(uuid).username()) || (allowAdmin && Sessions.get(uuid).admin()));
}
}

View File

@ -0,0 +1,4 @@
package at.nanopenguin.mtcg.application;
public record UserInfo(int id, String username, boolean admin) {
}

View File

@ -3,12 +3,17 @@ package at.nanopenguin.mtcg.application.service;
import at.nanopenguin.mtcg.application.SessionHandler;
import at.nanopenguin.mtcg.application.User;
import at.nanopenguin.mtcg.application.service.schemas.UserCredentials;
import at.nanopenguin.mtcg.application.service.schemas.UserData;
import at.nanopenguin.mtcg.db.DbQuery;
import at.nanopenguin.mtcg.db.SqlCommand;
import at.nanopenguin.mtcg.db.Table;
import at.nanopenguin.mtcg.http.HttpMethod;
import at.nanopenguin.mtcg.http.HttpRequest;
import at.nanopenguin.mtcg.http.HttpStatus;
import at.nanopenguin.mtcg.http.Response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.val;
import java.sql.SQLException;
import java.util.UUID;
@ -28,12 +33,41 @@ public class UserService implements Service {
if (request.getPath().split("/")[1].equals("users")) {
return switch (request.getMethod()) {
case GET -> new Response(HttpStatus.NOT_IMPLEMENTED);
case GET -> {
String username = request.getPath().split("/")[2];
if (request.getHttpHeader("Authorization") == null || !SessionHandler.getInstance().verifyUUID(UUID.fromString(request.getHttpHeader("Authorization").replaceFirst("^Bearer ", "")), username, true))
yield new Response(HttpStatus.UNAUTHORIZED);
val result = DbQuery.builder()
.command(SqlCommand.SELECT)
.table(Table.USERS)
.condition("username", username)
.executeQuery();
if (result.isEmpty()) yield new Response(HttpStatus.NOT_FOUND);
val row1 = result.get(0);
UserData userData = new UserData((String) row1.get("name"), (String) row1.get("bio"), (String) row1.get("image"));
yield new Response(HttpStatus.OK, "application/json", new ObjectMapper().writeValueAsString(userData));
}
case POST -> { // register new user
int success = User.create(new ObjectMapper().readValue(request.getBody(), UserCredentials.class));
yield new Response(success > 0 ? HttpStatus.CREATED : HttpStatus.CONFLICT);
}
case PUT -> new Response(HttpStatus.NOT_IMPLEMENTED); // new ObjectMapper().readValue(request.getBody(), UserData.class);
case PUT -> {
String username = request.getPath().split("/")[2];
UserData userData = new ObjectMapper().readValue(request.getBody(), UserData.class);
if (request.getHttpHeader("Authorization") == null || !SessionHandler.getInstance().verifyUUID(UUID.fromString(request.getHttpHeader("Authorization").replaceFirst("^Bearer ", "")), username, true))
yield new Response(HttpStatus.UNAUTHORIZED);
if (DbQuery.builder()
.command(SqlCommand.UPDATE)
.table(Table.USERS)
.parameter("name", userData.name())
.parameter("bio", userData.bio())
.parameter("image", userData.image())
.condition("username", username)
.executeUpdate() == 1) {
yield new Response(HttpStatus.OK);
}
yield new Response(HttpStatus.NOT_FOUND);
}
default -> new Response(HttpStatus.NOT_FOUND);
};
}
@ -42,7 +76,8 @@ public class UserService implements Service {
}
catch (ArrayIndexOutOfBoundsException e) {
return new Response(HttpStatus.BAD_REQUEST);
} catch (SQLException e) {
}
catch (SQLException e) {
System.out.println(e.getMessage());
return new Response(HttpStatus.INTERNAL);
}

View File

@ -32,11 +32,9 @@ public class HttpRequest {
this.httpHeaders.put(headerEntry[0], headerEntry[1]);
}
// this.body = this.httpHeaders.containsKey("Content-Length") ? new String(new char[Integer.parseInt(this.httpHeaders.get("Content-Length"))]) : null;
int contentLength = Integer.parseInt(this.httpHeaders.get("Content-Length"));
int contentLength = this.httpHeaders.containsKey("Content-Length") ? Integer.parseInt(this.httpHeaders.get("Content-Length")) : 0;
char[] charBuffer = new char[contentLength];
this.body = br.read(charBuffer, 0, contentLength) > 0 ? new String(charBuffer) : null;
return;
}

View File

@ -26,6 +26,7 @@ public class RequestHandler implements Runnable {
Response response;
responseBuilder: {
if (httpRequest.getMethod() == null) {
System.out.println("Thanks, postman");
return;
}