Add caching mechanism and improve error handling for AuthService
Introduced a caching layer to reduce redundant login code requests to the server, improving performance and reducing load. Updated related code to ensure better error logging and clean up unused variables. Adjusted event handling in ProxyPlayerListener for improved execution order and ban message deserialization.
This commit is contained in:
parent
d928ea4b87
commit
6ef20f8fd6
|
|
@ -199,7 +199,7 @@ public final class Config {
|
|||
YOUR_LOGIN_CODE = getString("messages.your-login-code", YOUR_LOGIN_CODE);
|
||||
}
|
||||
|
||||
public static String LOGIN_CODE_ENDPOINT = "https://alttd.com/auth/get_login_code/<uuid>";
|
||||
public static String LOGIN_CODE_ENDPOINT = "https://alttd.com/login/requestNewUserLogin/<uuid>";
|
||||
public static String LOGIN_ENDPOINT = "https://alttd.com/login";
|
||||
public static String SECRET = "";
|
||||
private static void site() {
|
||||
|
|
@ -207,7 +207,6 @@ public final class Config {
|
|||
byte[] randomBytes = new byte[256];
|
||||
new java.security.SecureRandom().nextBytes(randomBytes);
|
||||
SECRET = java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
|
||||
config.getNode("secret").setValue(SECRET);
|
||||
}
|
||||
SECRET = getString("secret", SECRET);
|
||||
LOGIN_ENDPOINT = getString("login-endpoint", LOGIN_ENDPOINT);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.alttd.webinterface.listeners;
|
|||
|
||||
import com.alttd.webinterface.config.Config;
|
||||
import com.alttd.webinterface.web_interact.AuthService;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.ResultedEvent;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||
|
|
@ -9,6 +10,7 @@ import com.velocitypowered.api.proxy.Player;
|
|||
import litebans.api.Database;
|
||||
import litebans.api.Entry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
|
|
@ -26,7 +28,7 @@ public class ProxyPlayerListener {
|
|||
public ProxyPlayerListener() {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@Subscribe(order = PostOrder.FIRST)
|
||||
public void playerLogin(@NotNull LoginEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
final UUID uuid = player.getUniqueId();
|
||||
|
|
@ -43,18 +45,17 @@ public class ProxyPlayerListener {
|
|||
|
||||
String displayMessage = ban.isPermanent() ? Config.PERM_BAN : Config.TEMP_BAN;
|
||||
try {
|
||||
miniMessage.deserialize(displayMessage, TagResolver.resolver(
|
||||
Component displayComponent = miniMessage.deserialize(displayMessage, TagResolver.resolver(
|
||||
Placeholder.component("base", miniMessage.deserialize(Config.BASE_MESSAGE, resolveBase(ban))),
|
||||
Placeholder.component("appeal_message", miniMessage.deserialize(Config.APPEAL_MESSAGE,
|
||||
resolveAppealMessage(uuid))),
|
||||
Placeholder.unparsed("duration", Instant.ofEpochMilli(ban.getDateEnd()).toString())));
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(displayComponent));
|
||||
} catch (IllegalStateException e) {
|
||||
log.error("Failed to deserialize ban message", e);
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(miniMessage.deserialize(
|
||||
"<red>Unable to display punishment and appeal code, please contact us via email at appeal@alttd.com</red>")));
|
||||
return;
|
||||
}
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(miniMessage.deserialize(ban.getReason())));
|
||||
}
|
||||
|
||||
private static @NotNull TagResolver resolveAppealMessage(UUID uuid) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.net.URI;
|
|||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -12,8 +13,13 @@ import com.alttd.webinterface.config.Config;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class AuthService {
|
||||
private static final Map<UUID, CacheEntry> cache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Asynchronously sends a GET request to the login endpoint with the required authorization header.
|
||||
|
|
@ -23,31 +29,57 @@ public class AuthService {
|
|||
* or an empty Optional otherwise
|
||||
*/
|
||||
public static @NotNull CompletableFuture<Optional<String>> getLoginCodeAsync(UUID uuid) {
|
||||
String loginUrl = Config.LOGIN_CODE_ENDPOINT.replaceAll("<uuid>", uuid.toString());
|
||||
|
||||
try (HttpClient client = HttpClient.newHttpClient()) {
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(loginUrl))
|
||||
.header("Authorization", "SECRET " + Config.SECRET)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
|
||||
.thenApply(response -> {
|
||||
if (response.statusCode() == 200) {
|
||||
String body = response.body();
|
||||
return Optional.ofNullable(body);
|
||||
} else {
|
||||
log.error("Failed to get login code. Status code: {}", response.statusCode());
|
||||
return Optional.<String>empty();
|
||||
}
|
||||
})
|
||||
.exceptionally(e -> {
|
||||
log.error("Exception occurred while getting login code", e);
|
||||
return Optional.empty();
|
||||
});
|
||||
Optional<String> cachedCode = getCachedCode(uuid);
|
||||
if (cachedCode.isPresent()) {
|
||||
return CompletableFuture.completedFuture(cachedCode);
|
||||
}
|
||||
|
||||
String loginUrl = Config.LOGIN_CODE_ENDPOINT.replaceAll("<uuid>", uuid.toString());
|
||||
log.info("Contacting server for login code at {}", loginUrl);
|
||||
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(loginUrl))
|
||||
.header("Authorization", "SECRET " + Config.SECRET)
|
||||
.GET()
|
||||
.build();
|
||||
log.info("Created request");
|
||||
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
|
||||
.thenApply(response -> {
|
||||
log.info("received response");
|
||||
if (response.statusCode() == 200) {
|
||||
String body = response.body();
|
||||
cache.put(uuid, new CacheEntry(body, Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(10))));
|
||||
client.close();
|
||||
return Optional.ofNullable(body);
|
||||
} else {
|
||||
log.error("Failed to get login code. Status code: {}", response.statusCode());
|
||||
client.close();
|
||||
return Optional.<String>empty();
|
||||
}
|
||||
})
|
||||
.exceptionally(e -> {
|
||||
log.error("Exception occurred while getting login code", e);
|
||||
client.close();
|
||||
return Optional.empty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static Optional<String> getCachedCode(UUID uuid) {
|
||||
CacheEntry cachedEntry = cache.get(uuid);
|
||||
if (cachedEntry != null) {
|
||||
if (cachedEntry.expiry.isAfter(Instant.now())) {
|
||||
return Optional.of(cachedEntry.code);
|
||||
}
|
||||
|
||||
if (cachedEntry.expiry.isBefore(Instant.now())) {
|
||||
cache.remove(uuid);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private record CacheEntry(String code, Instant expiry) { }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user