diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index a66d7aa30..29b72beff 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -35,7 +35,7 @@ import com.djrapitops.plan.system.settings.config.ConfigSystem; import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.systems.Systems; import com.djrapitops.plan.systems.cache.DataCache; import com.djrapitops.plan.systems.cache.GeolocationCache; @@ -237,7 +237,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin { @Override public void onDisable() { //Clears the page cache - PageCache.clearCache(); + ResponseCache.clearCache(); // Processes unprocessed processors if (processingQueue != null) { diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java b/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java index ab4e7b514..902145f99 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java @@ -32,6 +32,7 @@ public interface PlanPlugin extends IPlugin { UUID getServerUuid(); + @Deprecated InformationManager getInfoManager(); WebServer getWebServer(); diff --git a/Plan/src/main/java/com/djrapitops/plan/api/API.java b/Plan/src/main/java/com/djrapitops/plan/api/API.java index 306f29e0a..c47595ddb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/API.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/API.java @@ -89,7 +89,7 @@ public class API { } /** - * Condition if Players's Inspect page is cached to PageCache. + * Condition if Players's Inspect page is cached to ResponseCache. * * @param uuid UUID of the player. * @return true/false @@ -101,10 +101,10 @@ public class API { } /** - * Condition if Players's Inspect page is cached to PageCache of the providing WebServer. + * Condition if Players's Inspect page is cached to ResponseCache of the providing WebServer. *

- * Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's PageCache. - * Only Bukkit: Checks PageCache for page. + * Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's ResponseCache. + * Only Bukkit: Checks ResponseCache for page. * * @param uuid UUID of the player. * @return true/false @@ -114,7 +114,7 @@ public class API { } /** - * Cache Players's Inspect page to the PageCache of the providing WebServer. + * Cache Players's Inspect page to the ResponseCache of the providing WebServer. * * @param uuid UUID of the player. * @deprecated use {@code cachePlayerHtml} @@ -125,10 +125,10 @@ public class API { } /** - * Cache Players's Inspect page to the PageCache of the providing WebServer. + * Cache Players's Inspect page to the ResponseCache of the providing WebServer. *

* Using BungeeCord: Will send a {@code PostHtmlWebAPI} request after calculating the inspect page. - * Only Bukkit: Calculates inspect page and places it in the PageCache. + * Only Bukkit: Calculates inspect page and places it in the ResponseCache. * * @param uuid UUID of the player. * @deprecated use {@code cachePlayerHtml} diff --git a/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java new file mode 100644 index 000000000..e6c36f03a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java @@ -0,0 +1,21 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.api; + +import com.djrapitops.plan.data.plugin.PluginData; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public interface PlanAPI { + + static PlanAPI getInstance() { + throw new IllegalAccessError("Not yet implemented"); // TODO + } + + void registerPluginData(PluginData pluginData); +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java index 892bc4681..1616a186e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java @@ -1,27 +1,31 @@ -/* +/* * Licence is provided in the jar as license.yml also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml */ package com.djrapitops.plan.api.exceptions; +import com.djrapitops.plan.system.webserver.auth.FailReason; + /** * Thrown when WebUser can not be authorized (WebServer). * * @author Rsl1122 */ public class WebUserAuthException extends Exception { - public WebUserAuthException() { - } - public WebUserAuthException(String message) { - super(message); - } + private final FailReason failReason; - public WebUserAuthException(String message, Throwable cause) { - super(message, cause); + public WebUserAuthException(FailReason failReason) { + super(failReason.getReason()); + this.failReason = failReason; } public WebUserAuthException(Throwable cause) { - super(cause); + super(FailReason.ERROR.getReason(), cause); + this.failReason = FailReason.ERROR; + } + + public FailReason getFailReason() { + return failReason; } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/APIResponseHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/APIResponseHandler.java index 3369474df..005db193b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/APIResponseHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/APIResponseHandler.java @@ -4,10 +4,13 @@ */ package com.djrapitops.plan.system.webserver; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; import com.djrapitops.plan.system.webserver.response.*; import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse; +import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse; import com.djrapitops.plan.system.webserver.webapi.WebAPI; import com.djrapitops.plan.system.webserver.webapi.WebAPIManager; import com.djrapitops.plan.utilities.html.Html; @@ -40,29 +43,29 @@ public class APIResponseHandler { String[] args = target.split("/"); if ("/favicon.ico".equalsIgnoreCase(target)) { - return PageCache.loadPage(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico")); + return ResponseCache.loadResponse(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico")); } if ("/debug".equalsIgnoreCase(target)) { return new DebugPageResponse(); } if (target.endsWith(".css")) { - return PageCache.loadPage(PageId.CSS.of(target), () -> new CSSResponse(target)); + return ResponseCache.loadResponse(PageId.CSS.of(target), () -> new CSSResponse(target)); } if (target.endsWith(".js")) { - return PageCache.loadPage(PageId.JS.of(target), () -> new JavaScriptResponse(target)); + return ResponseCache.loadResponse(PageId.JS.of(target), () -> new JavaScriptResponse(target)); } if (args.length < 2 || !"api".equals(args[1])) { String address = PlanPlugin.getInstance().getInfoManager().getWebServerAddress() + target; String link = Html.LINK.parse(address, address); - return PageCache.loadPage(PageId.ERROR.of("Non-API Request"), () -> new NotFoundResponse("WebServer is in WebAPI-only mode, " + + return ResponseCache.loadResponse(PageId.ERROR.of("Non-API Request"), () -> new NotFoundResponse("WebServer is in WebAPI-only mode, " + "connect to the Bungee server instead: " + link)); } if (args.length < 3) { String error = "API Method not specified"; - return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); } String method = args[2]; @@ -74,7 +77,7 @@ public class APIResponseHandler { if (requestBody == null) { String error = "Error at reading the POST request." + "Note that the Encoding must be ISO-8859-1."; - return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); } Map variables = WebAPI.readVariables(requestBody); @@ -93,7 +96,7 @@ public class APIResponseHandler { if (!checkKey(sender)) { String error = "Server Key not given or invalid"; Log.debug("Request had invalid Server key: " + sender); - return PageCache.loadPage(PageId.ERROR.of(error), () -> { + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> { ForbiddenResponse forbidden = new ForbiddenResponse(); forbidden.setContent(error); return forbidden; @@ -103,7 +106,7 @@ public class APIResponseHandler { if (!webAPI.isAuthorized(accessKey)) { String error = "Access Key invalid"; Log.debug("Request had invalid Access key: " + accessKey); - return PageCache.loadPage(PageId.ERROR.of(error), () -> { + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> { ForbiddenResponse forbidden = new ForbiddenResponse(); forbidden.setContent(error); return forbidden; @@ -117,7 +120,7 @@ public class APIResponseHandler { if (api == null) { String error = "API Method not found"; Log.debug(error); - return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); } Response response = api.processRequest(PlanPlugin.getInstance(), variables); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java index 6b344f02b..f7825e030 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java @@ -4,12 +4,14 @@ */ package com.djrapitops.plan.system.webserver; +import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plugin.utilities.Verify; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import java.io.InputStream; import java.util.List; +import java.util.Optional; /** * Represents a HttpExchange Request. @@ -19,7 +21,7 @@ import java.util.List; * @author Rsl1122 */ public class Request { - private String auth; + private Authentication auth; private final String requestMethod; private final String target; @@ -30,27 +32,14 @@ public class Request { this.target = exchange.getRequestURI().toString(); this.exchange = exchange; - setAuth(exchange.getRequestHeaders()); } - public String getAuth() { - return auth; + public Optional getAuth() { + return Optional.ofNullable(auth); } - public void setAuth(Headers requestHeaders) { - List authorization = requestHeaders.get("Authorization"); - if (Verify.isEmpty(authorization)) { - return; - } - - String authLine = authorization.get(0); - if (authLine.contains("Basic ")) { - auth = authLine.split(" ")[1]; - } - } - - public boolean hasAuth() { - return auth != null; + public void setAuth(Authentication authentication) { + auth = authentication; } public String getRequestMethod() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java index 6bf5bba0d..5b6082e80 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java @@ -5,15 +5,19 @@ package com.djrapitops.plan.system.webserver; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.webserver.auth.Authentication; +import com.djrapitops.plan.system.webserver.auth.BasicAuthentication; import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plugin.api.Benchmark; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.utilities.Verify; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import java.io.IOException; +import java.util.List; /** * HttpHandler for WebServer request management. @@ -30,8 +34,11 @@ public class RequestHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) { + Headers requestHeaders = exchange.getRequestHeaders(); Headers responseHeaders = exchange.getResponseHeaders(); Request request = new Request(exchange); + request.setAuth(getAuthorization(requestHeaders)); + String requestString = request.toString(); Benchmark.start("", requestString); int responseCode = -1; @@ -55,5 +62,17 @@ public class RequestHandler implements HttpHandler { } } + private Authentication getAuthorization(Headers requestHeaders) { + List authorization = requestHeaders.get("Authorization"); + if (Verify.isEmpty(authorization)) { + return null; + } + + String authLine = authorization.get(0); + if (authLine.contains("Basic ")) { + return new BasicAuthentication(authLine.split(" ")[1]); + } + return null; + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java index 15dbe26f6..81e24d2b6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java @@ -9,49 +9,104 @@ import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.api.exceptions.WebUserAuthException; import com.djrapitops.plan.data.WebUser; import com.djrapitops.plan.database.tables.SecurityTable; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.auth.Authentication; +import com.djrapitops.plan.system.webserver.auth.FailReason; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; +import com.djrapitops.plan.system.webserver.pages.*; import com.djrapitops.plan.system.webserver.response.*; +import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse; import com.djrapitops.plan.utilities.PassEncryptUtil; import com.djrapitops.plan.utilities.uuid.UUIDUtility; import com.djrapitops.plugin.api.utility.log.Log; import java.sql.SQLException; -import java.util.Base64; -import java.util.Optional; -import java.util.UUID; +import java.util.*; /** * Handles choosing of the correct response to a request. * * @author Rsl1122 */ -public class ResponseHandler extends APIResponseHandler { +public class ResponseHandler extends TreePageHandler { + + private final boolean authRequired; private final boolean usingHttps; public ResponseHandler(WebServer webServer) { - super(); + authRequired = webServer.isAuthRequired(); this.usingHttps = webServer.isUsingHTTPS(); } + public void registerDefaultPages() { + registerPage("favicon.ico", new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico")); + registerPage("debug", new DebugPageHandler()); + registerPage("players", new PlayersPageHandler()); + registerPage("player", new PlayerPageHandler()); + + ServerPageHandler serverPageHandler = new ServerPageHandler(); + registerPage("network", serverPageHandler); + registerPage("server", serverPageHandler); + } + + public void registerWebAPIPages() { + + } + public Response getResponse(Request request) { - String target = request.getTarget(); - String[] args = target.split("/"); + String targetString = request.getTarget(); + List target = Arrays.asList(targetString.split("/")); + target.remove(0); try { - if ("/favicon.ico".equals(target)) { - return PageCache.loadPage(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico")); + Optional authentication = Optional.empty(); + if (authRequired) { + authentication = request.getAuth(); + if (!authentication.isPresent() && usingHttps) { + return DefaultResponses.BASIC_AUTH.get(); + } + + if (authentication.isPresent() && !authentication.get().isAuthorized(null)) { + return forbiddenResponse(0, 0); + } + } + + PageHandler pageHandler = getPageHandler(target); + if (pageHandler == null) { + if (targetString.endsWith(".css")) { + return ResponseCache.loadResponse(PageId.CSS.of(targetString), () -> new CSSResponse(targetString)); + } + if (targetString.endsWith(".js")) { + return ResponseCache.loadResponse(PageId.JS.of(targetString), () -> new JavaScriptResponse(targetString)); + } + return DefaultResponses.NOT_FOUND.get(); + } else { + if (authentication.isPresent() && authentication.get().isAuthorized(pageHandler.getPermission())) { + return forbiddenResponse(0, 0); + } + return pageHandler.getResponse(request, target); + } + } catch (WebUserAuthException e) { + return PromptAuthorizationResponse.getBasicAuthResponse(e); + } catch (Exception e) { + Log.toLog(this.getClass().getName(), e); + return new InternalErrorResponse(e, request.getTarget()); + } + + try { + if ("/favicon.ico".equals(targetString)) { + return ResponseCache.loadResponse(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico")); } if (request.isAPIRequest()) { return getAPIResponse(request); } - if (target.endsWith(".css")) { - return PageCache.loadPage(PageId.CSS.of(target), () -> new CSSResponse(target)); - } - if (target.endsWith(".js")) { - return PageCache.loadPage(PageId.JS.of(target), () -> new JavaScriptResponse(target)); - } UUID serverUUID = PlanPlugin.getInstance().getServerUuid(); @@ -61,7 +116,7 @@ public class ResponseHandler extends APIResponseHandler { } WebUser user = getUser(request.getAuth()); - int required = getRequiredPermLevel(target, user.getName()); + int required = getRequiredPermLevel(targetString, user.getName()); int permLevel = user.getPermLevel(); if (!isAuthorized(required, permLevel)) { @@ -79,7 +134,7 @@ public class ResponseHandler extends APIResponseHandler { case "debug": return new DebugPageResponse(); case "players": - return PageCache.loadPage(PageId.PLAYERS.id(), PlayersPageResponse::new); + return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new); case "player": return playerResponse(args); case "network": @@ -100,7 +155,7 @@ public class ResponseHandler extends APIResponseHandler { } } catch (WebUserAuthException e) { - return PageCache.loadPage(PageId.AUTH_PROMPT.id(), PromptAuthorizationResponse::new); + return ResponseCache.loadResponse(PageId.AUTH_PROMPT.id(), PromptAuthorizationResponse::getBasicAuthResponse); } catch (Exception e) { Log.toLog(this.getClass().getName(), e); return new InternalErrorResponse(e, request.getTarget()); @@ -108,7 +163,7 @@ public class ResponseHandler extends APIResponseHandler { } private Response forbiddenResponse(int required, int permLevel) { - return PageCache.loadPage(PageId.FORBIDDEN.id(), () -> + return ResponseCache.loadResponse(PageId.FORBIDDEN.of(required + "/" + permLevel), () -> new ForbiddenResponse("Unauthorized User.
" + "Make sure your user has the correct access level.
" + "This page requires permission level of " + required + ",
" @@ -119,31 +174,6 @@ public class ResponseHandler extends APIResponseHandler { return permLevel <= requiredPermLevel; } - private WebUser getUser(String auth) throws SQLException, PassEncryptUtil.InvalidHashException, PassEncryptUtil.CannotPerformOperationException, WebUserAuthException { - Base64.Decoder decoder = Base64.getDecoder(); - byte[] decoded = decoder.decode(auth); - String[] userInfo = new String(decoded).split(":"); - if (userInfo.length != 2) { - throw new WebUserAuthException("User and Password not specified"); - } - - String user = userInfo[0]; - String passwordRaw = userInfo[1]; - - SecurityTable securityTable = PlanPlugin.getInstance().getDB().getSecurityTable(); - if (!securityTable.userExists(user)) { - throw new WebUserAuthException("User Doesn't exist"); - } - - WebUser webUser = securityTable.getWebUser(user); - - boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash()); - if (!correctPass) { - throw new WebUserAuthException("User and Password do not match"); - } - return webUser; - } - private int getRequiredPermLevel(String target, String user) { String[] t = target.split("/"); if (t.length < 2) { @@ -180,7 +210,7 @@ public class ResponseHandler extends APIResponseHandler { case 0: return serverResponse(serverUUID); case 1: - return PageCache.loadPage(PageId.PLAYERS.id(), PlayersPageResponse::new); + return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new); case 2: return playerResponse(new String[]{"", "", user.getName()}); default: @@ -189,44 +219,12 @@ public class ResponseHandler extends APIResponseHandler { } private Response serverResponse(UUID serverUUID) { - return PageCache.loadPage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(plugin.getInfoManager())); - } - - private Response playerResponse(String[] args) { - if (args.length < 3) { - return PageCache.loadPage(PageId.NOT_FOUND.id(), NotFoundResponse::new); - } - - String playerName = args[2].trim(); - UUID uuid = UUIDUtility.getUUIDOf(playerName); - - if (uuid == null) { - String error = "Player has no UUID"; - return PageCache.loadPage(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error)); - } - - if (plugin.getDB().wasSeenBefore(uuid)) { - plugin.getInfoManager().cachePlayer(uuid); - Response response = PageCache.loadPage(PageId.PLAYER.of(uuid)); - // TODO Create a new method that places NotFoundResponse to PageCache instead. - if (response == null || response.getContent().contains("No Bukkit Servers were online to process this request")) { - PageCache.cachePage(PageId.PLAYER.of(uuid), () -> { - try { - return new InspectPageResponse(plugin.getInfoManager(), uuid); - } catch (ParseException e) { - return new InternalErrorResponse(e, this.getClass().getName()); - } - }); - response = PageCache.loadPage(PageId.PLAYER.of(uuid)); - } - return response; - } - return new NotFoundResponse("Player has not played on this server."); + return ResponseCache.loadResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(plugin.getInfoManager())); } private Response notFoundResponse() { String error = "404 Not Found"; - return PageCache.loadPage(PageId.NOT_FOUND.of("Wrong Page"), () -> { + return ResponseCache.loadResponse(PageId.NOT_FOUND.of("Wrong Page"), () -> { String url = plugin.getInfoManager().getWebServerAddress(); return new NotFoundResponse("Make sure you're accessing a link given by a command, Examples:

" + "

" + url + "/player/Playername
" + diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java new file mode 100644 index 000000000..55a459c10 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java @@ -0,0 +1,18 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.auth; + +import com.djrapitops.plan.api.exceptions.WebUserAuthException; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public interface Authentication { + + boolean isAuthorized(String permission) throws WebUserAuthException; + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java new file mode 100644 index 000000000..d0f141f8a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java @@ -0,0 +1,67 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.auth; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.api.exceptions.WebUserAuthException; +import com.djrapitops.plan.data.WebUser; +import com.djrapitops.plan.database.tables.SecurityTable; +import com.djrapitops.plan.utilities.PassEncryptUtil; + +import java.util.Base64; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class BasicAuthentication implements Authentication { + + private String authenticationString; + + private WebUser user; + + public BasicAuthentication(String authenticationString) { + this.authenticationString = authenticationString; + } + + @Override + public boolean isAuthorized(String permission) throws WebUserAuthException { + if (user == null) { + user = getUser(); + return user.hasPermission(permission); + } + return false; + } + + public WebUser getUser() throws WebUserAuthException { + Base64.Decoder decoder = Base64.getDecoder(); + byte[] decoded = decoder.decode(authenticationString); + String[] userInfo = new String(decoded).split(":"); + if (userInfo.length != 2) { + throw new WebUserAuthException(FailReason.USER_AND_PASS_NOT_SPECIFIED); + } + + String user = userInfo[0]; + String passwordRaw = userInfo[1]; + + try { + SecurityTable securityTable = PlanPlugin.getInstance().getDB().getSecurityTable(); + if (!securityTable.userExists(user)) { + throw new WebUserAuthException(FailReason.USER_DOES_NOT_EXIST); + } + + WebUser webUser = securityTable.getWebUser(user); + + boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash()); + if (!correctPass) { + throw new WebUserAuthException(FailReason.USER_PASS_MISMATCH); + } + return webUser; + } catch (Exception e) { + throw new WebUserAuthException(e); + } + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java new file mode 100644 index 000000000..a3273dea4 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java @@ -0,0 +1,27 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.auth; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public enum FailReason { + USER_AND_PASS_NOT_SPECIFIED("User and Password not specified"), + USER_DOES_NOT_EXIST("User does not exist"), + USER_PASS_MISMATCH("User and Password did not match"), + ERROR("Authentication failed due to error"); + + private final String reason; + + FailReason(String reason) { + this.reason = reason; + } + + public String getReason() { + return reason; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageId.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageId.java index 35d5fefeb..8359fe57a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageId.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageId.java @@ -7,7 +7,7 @@ package com.djrapitops.plan.system.webserver.pagecache; import java.util.UUID; /** - * Enum class for "magic" PageCache identifier values. + * Enum class for "magic" ResponseCache identifier values. * * @author Rsl1122 */ diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageCache.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/ResponseCache.java similarity index 74% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageCache.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/ResponseCache.java index d9adebf4d..9e32b912f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/PageCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pagecache/ResponseCache.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.system.webserver.pagecache; -import com.djrapitops.plan.system.webserver.response.InspectPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; import com.djrapitops.plan.system.webserver.response.Response; import java.util.HashMap; @@ -17,14 +17,14 @@ import java.util.function.Predicate; * @author Fuzzlemann * @since 3.6.0 */ -public class PageCache { +public class ResponseCache { - private static final Map pageCache = new HashMap<>(); + private static final Map cache = new HashMap<>(); /** * Constructor used to hide the public constructor */ - private PageCache() { + private ResponseCache() { throw new IllegalStateException("Utility class"); } @@ -40,8 +40,8 @@ public class PageCache { * @param loader The {@link PageLoader} (How should it load the page if it's not cached) * @return The Response that was cached or created by the {@link PageLoader loader} */ - public static Response loadPage(String identifier, PageLoader loader) { - Response response = loadPage(identifier); + public static Response loadResponse(String identifier, PageLoader loader) { + Response response = loadResponse(identifier); if (response != null) { return response; @@ -49,7 +49,7 @@ public class PageCache { response = loader.createResponse(); - pageCache.put(identifier, response); + cache.put(identifier, response); return response; } @@ -60,8 +60,8 @@ public class PageCache { * @param identifier The identifier of the page * @return The Response that was cached or {@code null} if it wasn't */ - public static Response loadPage(String identifier) { - return pageCache.get(identifier); + public static Response loadResponse(String identifier) { + return cache.get(identifier); } /** @@ -70,10 +70,10 @@ public class PageCache { * Currently supported copyable responses: InspectPageResponse * * @param identifier The identifier of the page - * @return Copied Response of loadPage, so that cache contents are not changed. + * @return Copied Response of loadResponse, so that cache contents are not changed. */ - public static Response copyPage(String identifier, PageLoader loader) { - Response response = loadPage(identifier, loader); + public static Response copyResponse(String identifier, PageLoader loader) { + Response response = loadResponse(identifier, loader); if (response instanceof InspectPageResponse) { return InspectPageResponse.copyOf((InspectPageResponse) response); } @@ -88,9 +88,9 @@ public class PageCache { * @param identifier The identifier of the page * @param loader The {@link PageLoader} (How it should load the page) */ - public static void cachePage(String identifier, PageLoader loader) { + public static void cacheResponse(String identifier, PageLoader loader) { Response response = loader.createResponse(); - pageCache.put(identifier, response); + cache.put(identifier, response); } /** @@ -100,7 +100,7 @@ public class PageCache { * @return true if the page is cached */ public static boolean isCached(String identifier) { - return pageCache.containsKey(identifier); + return cache.containsKey(identifier); } /** @@ -109,9 +109,9 @@ public class PageCache { * @param filter a predicate which returns true for entries to be removed */ public static void removeIf(Predicate filter) { - for (String identifier : pageCache.keySet()) { + for (String identifier : cache.keySet()) { if (filter.test(identifier)) { - pageCache.remove(identifier); + cache.remove(identifier); } } } @@ -120,6 +120,6 @@ public class PageCache { * Clears the cache from all its contents. */ public static void clearCache() { - pageCache.clear(); + cache.clear(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java new file mode 100644 index 000000000..785d85acb --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java @@ -0,0 +1,24 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse; + +import java.util.List; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class DebugPageHandler extends PageHandler { + + @Override + public Response getResponse(Request request, List target) { + return new DebugPageResponse(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DefaultResponses.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DefaultResponses.java new file mode 100644 index 000000000..b43c9951c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DefaultResponses.java @@ -0,0 +1,33 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse; +import com.djrapitops.plan.system.webserver.response.Response; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public enum DefaultResponses { + NOT_FOUND( + new NotFoundResponse("Make sure you're accessing a link given by a command, Examples:

" + + "

/player/PlayerName
" + + "/server/ServerName

") + ), + BASIC_AUTH(PromptAuthorizationResponse.getBasicAuthResponse()); + + private final Response response; + + DefaultResponses(Response response) { + this.response = response; + } + + public Response get() { + return response; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java new file mode 100644 index 000000000..a87d788a6 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java @@ -0,0 +1,26 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.response.Response; + +import java.util.List; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public abstract class PageHandler { + + protected String permission = "*"; + + public abstract Response getResponse(Request request, List target); + + public String getPermission() { + return permission; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java new file mode 100644 index 000000000..3b3bb0bbd --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java @@ -0,0 +1,67 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.api.exceptions.ParseException; +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.pagecache.PageId; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; +import com.djrapitops.plan.utilities.uuid.UUIDUtility; + +import java.util.List; +import java.util.UUID; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class PlayerPageHandler extends PageHandler { + + public PlayerPageHandler() { + permission = "special_player"; + } + + @Override + public Response getResponse(Request request, List target) { + if (target.isEmpty()) { + return DefaultResponses.NOT_FOUND.get(); + } + + String playerName = target.get(0); + UUID uuid = UUIDUtility.getUUIDOf(playerName); + + if (uuid == null) { + return notFound("Player has no UUID"); + } + + if (PlanPlugin.getInstance().getDB().wasSeenBefore(uuid)) { + PlanPlugin.getInstance().getInfoManager().cachePlayer(uuid); + Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + // TODO Create a new method that places NotFoundResponse to ResponseCache instead. + if (response == null || response.getContent().contains("No Bukkit Servers were online to process this request")) { + ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> { + try { + return new InspectPageResponse(PlanPlugin.getInstance().getInfoManager(), uuid); + } catch (ParseException e) { + return new InternalErrorResponse(e, this.getClass().getName()); + } + }); + response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + } + return response; + } + return notFound("Player has not played on this server."); + } + + private Response notFound(String error) { + return ResponseCache.loadResponse(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java new file mode 100644 index 000000000..9104b12f4 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java @@ -0,0 +1,30 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.pagecache.PageId; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse; + +import java.util.List; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class PlayersPageHandler extends PageHandler { + + public PlayersPageHandler() { + permission = "players"; + } + + @Override + public Response getResponse(Request request, List target) { + return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java new file mode 100644 index 000000000..f4af237c3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java @@ -0,0 +1,27 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.response.Response; + +import java.util.List; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class ServerPageHandler extends PageHandler { + + public ServerPageHandler() { + permission = "server"; + } + + @Override + public Response getResponse(Request request, List target) { + return null; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java new file mode 100644 index 000000000..b647094e0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java @@ -0,0 +1,53 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package com.djrapitops.plan.system.webserver.pages; + +import com.djrapitops.plan.system.webserver.Request; +import com.djrapitops.plan.system.webserver.response.Response; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public abstract class TreePageHandler extends PageHandler { + + private Map pages; + + public TreePageHandler() { + pages = new HashMap<>(); + } + + public void registerPage(String targetPage, PageHandler handler) { + pages.put(targetPage, handler); + } + + public void registerPage(String targetPage, Response response) { + pages.put(targetPage, new PageHandler() { + @Override + public Response getResponse(Request request, List target) { + return response; + } + }); + } + + @Override + public Response getResponse(Request request, List target) { + PageHandler pageHandler = getPageHandler(target); + return pageHandler != null + ? pageHandler.getResponse(request, target) + : DefaultResponses.NOT_FOUND.get(); + } + + public PageHandler getPageHandler(List target) { + String targetPage = target.get(0); + target.remove(0); + return pages.get(targetPage); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java index 5b3cadd23..d8ad5ef78 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java @@ -4,6 +4,7 @@ */ package com.djrapitops.plan.system.webserver.response; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plugin.utilities.Verify; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java index f15892e74..eb8481520 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java @@ -1,5 +1,9 @@ package com.djrapitops.plan.system.webserver.response; +import com.djrapitops.plan.api.exceptions.WebUserAuthException; +import com.djrapitops.plan.system.webserver.auth.FailReason; +import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; +import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.html.Html; /** @@ -8,15 +12,43 @@ import com.djrapitops.plan.utilities.html.Html; */ public class PromptAuthorizationResponse extends ErrorResponse { - public PromptAuthorizationResponse() { - super.setHeader("HTTP/1.1 401 Access Denied\r\n" + private PromptAuthorizationResponse() { + super.setTitle(Html.FONT_AWESOME_ICON.parse("lock") + " 401 Unauthorized"); + } + + public static PromptAuthorizationResponse getBasicAuthResponse() { + PromptAuthorizationResponse response = new PromptAuthorizationResponse(); + response.setHeader("HTTP/1.1 401 Access Denied\r\n" + "WWW-Authenticate: Basic realm=\"/\";"); - super.setTitle(Html.FONT_AWESOME_ICON.parse("lock")+" 401 Unauthorized"); - super.setParagraph("Authentication Failed.
" + response.setParagraph("Authentication Failed.
" + "- Ensure you have registered a user with /plan register
" + "- Check that the username and password are correct
" + "- Username and password are case-sensitive
" + "
If you have forgotten your password, ask a staff member to delete your old user and re-register."); - super.replacePlaceholders(); + response.replacePlaceholders(); + return response; + } + + public static PromptAuthorizationResponse getBasicAuthResponse(WebUserAuthException e) { + PromptAuthorizationResponse response = new PromptAuthorizationResponse(); + response.setHeader("HTTP/1.1 401 Access Denied\r\n" + + "WWW-Authenticate: Basic realm=\"/\";"); + + FailReason failReason = e.getFailReason(); + String reason = failReason.getReason(); + + if (failReason == FailReason.ERROR) { + StringBuilder errorBuilder = new StringBuilder("

");
+            for (String line : FormatUtils.getStackTrace(e.getCause())) {
+                errorBuilder.append(line);
+            }
+            errorBuilder.append("
"); + + reason += errorBuilder.toString(); + } + + response.setParagraph("Authentication Failed.
Reason: " + reason); + response.replacePlaceholders(); + return response; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java similarity index 92% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ErrorResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java index 8924eed88..3f509c9e9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java @@ -2,9 +2,10 @@ * Licence is provided in the jar as license.yml also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml */ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.errors; import com.djrapitops.plan.settings.theme.Theme; +import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plugin.api.utility.log.Log; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ForbiddenResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java similarity index 90% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ForbiddenResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java index 739dda270..347a0b514 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ForbiddenResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.errors; import com.djrapitops.plan.utilities.html.Html; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InternalErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InternalErrorResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java index f9496b88f..e9cf480e4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InternalErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.errors; import com.djrapitops.plan.utilities.html.Html; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/NotFoundResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java similarity index 90% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/NotFoundResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java index f083edec7..429fd1ea5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/NotFoundResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.errors; import com.djrapitops.plan.utilities.html.Html; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/AnalysisPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java similarity index 90% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/AnalysisPageResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java index df7e21c40..8ef5faeae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/AnalysisPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java @@ -1,7 +1,9 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.Plan; import com.djrapitops.plan.data.AnalysisData; +import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; +import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.systems.info.BukkitInformationManager; import com.djrapitops.plan.systems.info.InformationManager; import com.djrapitops.plugin.task.AbsRunnable; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DebugPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java similarity index 98% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DebugPageResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java index 20e32ffc7..855ee3cd8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DebugPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java @@ -2,11 +2,12 @@ * Licence is provided in the jar as license.yml also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml */ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.ServerVariableHolder; +import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.systems.info.server.BungeeServerInfoManager; import com.djrapitops.plan.systems.info.server.ServerInfo; import com.djrapitops.plan.utilities.file.FileUtil; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InspectPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java similarity index 93% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InspectPageResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java index 36cfa3582..7a548b675 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/InspectPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java @@ -1,7 +1,8 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.settings.theme.Theme; +import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.systems.info.InformationManager; import org.apache.commons.lang3.text.StrSubstitutor; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PlayersPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PlayersPageResponse.java rename to Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java index 71819569f..e9220fecb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PlayersPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.system.webserver.response; +package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.container.GeoInfo; @@ -8,6 +8,8 @@ import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.database.Database; import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.analysis.AnalysisUtils; import com.djrapitops.plan.utilities.comparators.GeoInfoComparator; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/WebAPI.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/WebAPI.java index a17d1a798..0eaa1b885 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/WebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/WebAPI.java @@ -7,9 +7,9 @@ package com.djrapitops.plan.system.webserver.webapi; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.*; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; -import com.djrapitops.plan.system.webserver.response.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse; import com.djrapitops.plan.system.webserver.response.api.SuccessResponse; @@ -165,11 +165,11 @@ public abstract class WebAPI { }; protected Response success() { - return PageCache.loadPage(PageId.TRUE.id(), SuccessResponse::new); + return ResponseCache.loadResponse(PageId.TRUE.id(), SuccessResponse::new); } protected Response fail(String reason) { - return PageCache.loadPage(PageId.FALSE.id(), () -> { + return ResponseCache.loadResponse(PageId.FALSE.id(), () -> { NotFoundResponse notFoundResponse = new NotFoundResponse(""); notFoundResponse.setContent(reason); return notFoundResponse; @@ -177,7 +177,7 @@ public abstract class WebAPI { } protected Response badRequest(String error) { - return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); + return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error)); } private String parseVariables() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/PostHtmlWebAPI.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/PostHtmlWebAPI.java index c257d0b08..846690594 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/PostHtmlWebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/PostHtmlWebAPI.java @@ -7,10 +7,10 @@ package com.djrapitops.plan.system.webserver.webapi.bungee; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.WebAPIException; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; -import com.djrapitops.plan.system.webserver.response.AnalysisPageResponse; -import com.djrapitops.plan.system.webserver.response.InspectPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.webapi.WebAPI; import com.djrapitops.plan.systems.info.InformationManager; @@ -55,14 +55,14 @@ public class PostHtmlWebAPI extends WebAPI { Map map = new HashMap<>(); map.put("networkName", Settings.BUNGEE_NETWORK_NAME.toString()); - PageCache.cachePage(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(infoManager, UUID.fromString(uuid), StrSubstitutor.replace(html, map))); + ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(infoManager, UUID.fromString(uuid), StrSubstitutor.replace(html, map))); if (Settings.ANALYSIS_EXPORT.isTrue()) { HtmlExport.exportPlayer(plugin, UUID.fromString(uuid)); } break; case "analysisPage": String sender = variables.get("sender"); - PageCache.cachePage(PageId.SERVER.of(sender), () -> new AnalysisPageResponse(html)); + ResponseCache.cacheResponse(PageId.SERVER.of(sender), () -> new AnalysisPageResponse(html)); if (Settings.ANALYSIS_EXPORT.isTrue()) { HtmlExport.exportServer(plugin, UUID.fromString(sender)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/RequestSetupWebAPI.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/RequestSetupWebAPI.java index 35326754d..74e2c5d8b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/RequestSetupWebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/webapi/bungee/RequestSetupWebAPI.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.WebAPIException; -import com.djrapitops.plan.system.webserver.response.ForbiddenResponse; +import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.webapi.WebAPI; import com.djrapitops.plan.systems.info.server.ServerInfo; diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/info/BukkitInformationManager.java b/Plan/src/main/java/com/djrapitops/plan/systems/info/BukkitInformationManager.java index f6492a00c..679f968af 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/info/BukkitInformationManager.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/info/BukkitInformationManager.java @@ -15,9 +15,14 @@ import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; import com.djrapitops.plan.system.webserver.response.*; +import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; import com.djrapitops.plan.system.webserver.webapi.WebAPIManager; import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalysisReadyWebAPI; import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalyzeWebAPI; @@ -41,7 +46,7 @@ import java.sql.SQLException; import java.util.*; /** - * Manages the Information going to the PageCache. + * Manages the Information going to the ResponseCache. *

* This means Inspect and Analysis pages as well as managing what is sent to Bungee WebServer when one is in use. * @@ -115,7 +120,7 @@ public class BukkitInformationManager extends InformationManager { } } } else { - PageCache.cachePage(PageId.PLAYER.of(uuid), () -> { + ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> { try { return new InspectPageResponse(this, uuid); } catch (ParseException e) { @@ -188,7 +193,7 @@ public class BukkitInformationManager extends InformationManager { } } else { pluginsTabContents.put(uuid, contents); - Response inspectResponse = PageCache.loadPage(PageId.PLAYER.of(uuid)); + Response inspectResponse = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); if (inspectResponse != null && inspectResponse instanceof InspectPageResponse) { ((InspectPageResponse) inspectResponse).setInspectPagePluginsTab(contents); } @@ -231,7 +236,7 @@ public class BukkitInformationManager extends InformationManager { return isAnalysisCached(serverUUID); } } - return PageCache.isCached(PageId.SERVER.of(serverUUID)); + return ResponseCache.isCached(PageId.SERVER.of(serverUUID)); } private WebAPIManager getWebAPI() { @@ -306,7 +311,7 @@ public class BukkitInformationManager extends InformationManager { } } else { UUID serverUUID = Plan.getServerUUID(); - PageCache.cachePage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html)); + ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html)); if (Settings.ANALYSIS_EXPORT.isTrue()) { HtmlExport.exportServer(plugin, serverUUID); } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/info/BungeeInformationManager.java b/Plan/src/main/java/com/djrapitops/plan/systems/info/BungeeInformationManager.java index e28a1e1a0..085d73d07 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/info/BungeeInformationManager.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/info/BungeeInformationManager.java @@ -10,9 +10,13 @@ import com.djrapitops.plan.api.exceptions.WebAPIConnectionFailException; import com.djrapitops.plan.api.exceptions.WebAPIException; import com.djrapitops.plan.api.exceptions.WebAPINotFoundException; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; import com.djrapitops.plan.system.webserver.response.*; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; import com.djrapitops.plan.system.webserver.webapi.WebAPIManager; import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalysisReadyWebAPI; import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalyzeWebAPI; @@ -35,7 +39,7 @@ import java.util.function.Function; import java.util.stream.Collectors; /** - * Manages information going to the PageCache from Bukkit servers. + * Manages information going to the ResponseCache from Bukkit servers. * * @author Rsl1122 */ @@ -233,7 +237,7 @@ public class BungeeInformationManager extends InformationManager { */ @Override public boolean isAnalysisCached(UUID serverUUID) { - return PageCache.isCached(PageId.SERVER.of(serverUUID)); + return ResponseCache.isCached(PageId.SERVER.of(serverUUID)); } /** @@ -246,7 +250,7 @@ public class BungeeInformationManager extends InformationManager { */ @Override public String getPlayerHtml(UUID uuid) { - Response response = PageCache.copyPage(PageId.PLAYER.of(uuid), + Response response = ResponseCache.copyResponse(PageId.PLAYER.of(uuid), () -> new NotFoundResponse("No Bukkit Servers were online to process this request")); if (response instanceof InspectPageResponse) { ((InspectPageResponse) response).setInspectPagePluginsTab(getPluginsTabContent(uuid)); @@ -310,7 +314,7 @@ public class BungeeInformationManager extends InformationManager { Map perServerPluginsTab = pluginsTabContent.getOrDefault(uuid, new HashMap<>()); perServerPluginsTab.put(serverUUID, html); pluginsTabContent.put(uuid, perServerPluginsTab); - Response inspectResponse = PageCache.loadPage(PageId.PLAYER.of(uuid)); + Response inspectResponse = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); if (inspectResponse != null && inspectResponse instanceof InspectPageResponse) { ((InspectPageResponse) inspectResponse).setInspectPagePluginsTab(getPluginsTabContent(uuid)); } @@ -368,7 +372,7 @@ public class BungeeInformationManager extends InformationManager { @Override public void updateNetworkPageContent() { UUID serverUUID = PlanPlugin.getInstance().getServerUuid(); - PageCache.cachePage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(this)); + ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(this)); if (Settings.ANALYSIS_EXPORT.isTrue()) { HtmlExport.exportServer(plugin, serverUUID); } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/info/InformationManager.java b/Plan/src/main/java/com/djrapitops/plan/systems/info/InformationManager.java index 8c6991a1a..3904741ee 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/info/InformationManager.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/info/InformationManager.java @@ -5,7 +5,7 @@ package com.djrapitops.plan.systems.info; import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; import com.djrapitops.plan.systems.cache.DataCache; import com.djrapitops.plan.systems.cache.SessionCache; @@ -47,7 +47,7 @@ public abstract class InformationManager { } public boolean isCached(UUID uuid) { - return PageCache.isCached(PageId.PLAYER.of(uuid)); + return ResponseCache.isCached(PageId.PLAYER.of(uuid)); } public abstract String getPlayerHtml(UUID uuid) throws ParseException; diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/processing/info/InspectCacheRequestProcessor.java b/Plan/src/main/java/com/djrapitops/plan/systems/processing/info/InspectCacheRequestProcessor.java index 053e3cc3c..dd841d352 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/processing/info/InspectCacheRequestProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/processing/info/InspectCacheRequestProcessor.java @@ -17,7 +17,7 @@ import com.djrapitops.plugin.command.ISender; import java.util.UUID; /** - * Sends a request to cache players inspect page to the PageCache on the appropriate WebServer. + * Sends a request to cache players inspect page to the ResponseCache on the appropriate WebServer. * * @author Rsl1122 */ diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java index a6306a435..092809fd0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java @@ -6,6 +6,8 @@ import org.apache.commons.lang3.StringUtils; import org.bukkit.Location; import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; /** * @author Rsl1122 @@ -241,4 +243,29 @@ public class FormatUtils { return b.append("xx").toString(); } + + /** + * Gets lines for stack trace recursively. + * + * @param throwable + * @return + */ + public static List getStackTrace(Throwable throwable) { + List stackTrace = new ArrayList<>(); + stackTrace.add(throwable.toString()); + for (StackTraceElement element : throwable.getStackTrace()) { + stackTrace.add(" " + element.toString()); + } + + Throwable cause = throwable.getCause(); + if (cause != null) { + List causeTrace = getStackTrace(cause); + if (!causeTrace.isEmpty()) { + causeTrace.set(0, "Caused by: " + causeTrace.get(0)); + stackTrace.addAll(causeTrace); + } + } + + return stackTrace; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java index d121b5c87..05baae732 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java @@ -11,8 +11,8 @@ import com.djrapitops.plan.database.Database; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.Msg; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.response.ErrorResponse; -import com.djrapitops.plan.system.webserver.response.InternalErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; +import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; import com.djrapitops.plan.systems.cache.DataCache; import com.djrapitops.plan.systems.cache.SessionCache; import com.djrapitops.plan.systems.info.BukkitInformationManager; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java index 896efa2cd..40719156d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java @@ -11,7 +11,7 @@ import java.util.ConcurrentModificationException; import java.util.UUID; /** - * Task that exports a single Analysis page if it is in PageCache. + * Task that exports a single Analysis page if it is in ResponseCache. * * @author Rsl1122 */ diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java index f7088db5b..ff1654294 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java @@ -8,7 +8,7 @@ import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.container.UserInfo; import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.settings.theme.ThemeVal; -import com.djrapitops.plan.system.webserver.response.PlayersPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse; import com.djrapitops.plan.system.webserver.webapi.bungee.PostHtmlWebAPI; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plugin.api.utility.log.Log; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java index f51cf8fc9..2f23feb41 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java @@ -5,7 +5,7 @@ package com.djrapitops.plan.utilities.file.export; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageId; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plugin.api.Check; @@ -73,7 +73,7 @@ public abstract class SpecificExport extends AbsRunnable { } protected void exportAvailablePlayerPage(UUID uuid, String name) throws IOException { - Response response = PageCache.loadPage(PageId.PLAYER.of(uuid)); + Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); if (response == null) { return; } @@ -90,7 +90,7 @@ public abstract class SpecificExport extends AbsRunnable { protected void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException { - Response response = PageCache.loadPage(PageId.SERVER.of(serverUUID)); + Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); if (response == null) { return; } diff --git a/Plan/test/main/java/com/djrapitops/plan/data/cache/PageCacheTest.java b/Plan/test/main/java/com/djrapitops/plan/data/cache/ResponseCacheTest.java similarity index 60% rename from Plan/test/main/java/com/djrapitops/plan/data/cache/PageCacheTest.java rename to Plan/test/main/java/com/djrapitops/plan/data/cache/ResponseCacheTest.java index 5918c4059..73ce5d6ce 100644 --- a/Plan/test/main/java/com/djrapitops/plan/data/cache/PageCacheTest.java +++ b/Plan/test/main/java/com/djrapitops/plan/data/cache/ResponseCacheTest.java @@ -1,6 +1,6 @@ package com.djrapitops.plan.data.cache; -import com.djrapitops.plan.system.webserver.pagecache.PageCache; +import com.djrapitops.plan.system.webserver.pagecache.ResponseCache; import com.djrapitops.plan.system.webserver.pagecache.PageLoader; import com.djrapitops.plan.system.webserver.response.Response; import org.junit.Test; @@ -11,7 +11,7 @@ import static junit.framework.TestCase.*; /** * @author Fuzzlemann */ -public class PageCacheTest { +public class ResponseCacheTest { private final String IDENTIFIER = RandomData.randomString(10); private final String RESPONSE_STRING = RandomData.randomString(10); private final Response RESPONSE = new Response() { @@ -34,29 +34,29 @@ public class PageCacheTest { public void testCache() { Response expResponse = LOADER.createResponse(); - assertFalse(PageCache.isCached(IDENTIFIER)); + assertFalse(ResponseCache.isCached(IDENTIFIER)); - Response response = PageCache.loadPage(IDENTIFIER, LOADER); - assertTrue(PageCache.isCached(IDENTIFIER)); + Response response = ResponseCache.loadResponse(IDENTIFIER, LOADER); + assertTrue(ResponseCache.isCached(IDENTIFIER)); assertEquals(expResponse, response); } @Test public void testClearCache() { - PageCache.cachePage(IDENTIFIER, LOADER); - assertTrue(PageCache.isCached(IDENTIFIER)); + ResponseCache.cacheResponse(IDENTIFIER, LOADER); + assertTrue(ResponseCache.isCached(IDENTIFIER)); - PageCache.clearCache(); - assertFalse(PageCache.isCached(IDENTIFIER)); + ResponseCache.clearCache(); + assertFalse(ResponseCache.isCached(IDENTIFIER)); } @Test public void testRemoveIf() { - PageCache.cachePage(IDENTIFIER, LOADER); - assertTrue(PageCache.isCached(IDENTIFIER)); + ResponseCache.cacheResponse(IDENTIFIER, LOADER); + assertTrue(ResponseCache.isCached(IDENTIFIER)); - PageCache.removeIf(identifier -> identifier.equals(IDENTIFIER)); - assertFalse(PageCache.isCached(IDENTIFIER)); + ResponseCache.removeIf(identifier -> identifier.equals(IDENTIFIER)); + assertFalse(ResponseCache.isCached(IDENTIFIER)); } }