From 77dbc74cc5b0991a2213424201c3c3b87a863195 Mon Sep 17 00:00:00 2001 From: Rsl1122 <24460436+Rsl1122@users.noreply.github.com> Date: Sat, 29 Feb 2020 11:18:59 +0200 Subject: [PATCH] Refactored Root page redirect - Fixed issue where response code was not set - Fixed ResponseSender not setting values for response headers - Changed ResponseResolver to mostly use Response instead of _old --- .../web/resolver/ResponseBuilder.java | 3 + .../rendering/pages/ErrorMessagePage.java | 13 ++- .../delivery/rendering/pages/PageFactory.java | 7 ++ .../delivery/webserver/RequestHandler.java | 36 +++---- .../delivery/webserver/ResponseResolver.java | 38 +++---- .../delivery/webserver/ResponseSender.java | 4 +- .../webserver/pages/RootPageResolver.java | 59 +++++----- .../webserver/response/ResponseFactory.java | 101 ++++++++++++++---- .../webserver/response/Response_old.java | 22 ++-- 9 files changed, 173 insertions(+), 110 deletions(-) diff --git a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/ResponseBuilder.java b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/ResponseBuilder.java index 925c1505d..2dd6112f2 100644 --- a/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/ResponseBuilder.java +++ b/Plan/api/src/main/java/com/djrapitops/plan/delivery/web/resolver/ResponseBuilder.java @@ -49,6 +49,7 @@ public class ResponseBuilder { * @return this builder. */ public ResponseBuilder setStatus(int code) { + response.code = code; return this; } @@ -85,6 +86,8 @@ public class ResponseBuilder { } public ResponseBuilder setContent(String content, Charset charset) { + if (content == null) return setContent(new byte[0]); + if (charset == null) return setContent(content); // UTF-8 used String mimeType = getMimeType(); response.charset = charset; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/ErrorMessagePage.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/ErrorMessagePage.java index 5c3b26c03..b43ef700e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/ErrorMessagePage.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/ErrorMessagePage.java @@ -29,26 +29,35 @@ import com.djrapitops.plan.version.VersionCheckSystem; public class ErrorMessagePage implements Page { private final String template; + private final Icon icon; private final String errorTitle; private final String errorMsg; private final VersionCheckSystem versionCheckSystem; public ErrorMessagePage( - String template, String errorTitle, String errorMsg, + String template, Icon icon, String errorTitle, String errorMsg, VersionCheckSystem versionCheckSystem ) { this.template = template; + this.icon = icon; this.errorTitle = errorTitle; this.errorMsg = errorMsg; this.versionCheckSystem = versionCheckSystem; } + public ErrorMessagePage( + String template, String errorTitle, String errorMsg, + VersionCheckSystem versionCheckSystem + ) { + this(template, Icon.called("exclamation-circle").build(), errorTitle, errorMsg, versionCheckSystem); + } + @Override public String toHtml() { PlaceholderReplacer placeholders = new PlaceholderReplacer(); - placeholders.put("title", Icon.called("exclamation-circle") + " " + errorTitle); + placeholders.put("title", icon.toHtml() + " " + errorTitle); placeholders.put("titleText", errorTitle); placeholders.put("paragraph", errorMsg); placeholders.put("version", versionCheckSystem.getUpdateButton().orElse(versionCheckSystem.getCurrentVersionButton())); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/PageFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/PageFactory.java index 855658967..7528bcffb 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/PageFactory.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/pages/PageFactory.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.rendering.pages; import com.djrapitops.plan.delivery.domain.container.PlayerContainer; import com.djrapitops.plan.delivery.formatting.Formatters; +import com.djrapitops.plan.delivery.rendering.html.icon.Icon; import com.djrapitops.plan.exceptions.connection.NotFoundException; import com.djrapitops.plan.extension.implementation.results.ExtensionData; import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionPlayerDataQuery; @@ -182,6 +183,12 @@ public class PageFactory { versionCheckSystem.get()); } + public Page errorPage(Icon icon, String title, String error) throws IOException { + return new ErrorMessagePage( + getResource("web/error.html"), icon, title, error, + versionCheckSystem.get()); + } + public String getResource(String name) throws IOException { return files.get().getCustomizableResourceOrDefault(name).asString(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java index 45808debf..89a11cb5a 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java @@ -16,12 +16,10 @@ */ package com.djrapitops.plan.delivery.webserver; +import com.djrapitops.plan.delivery.web.resolver.Response; import com.djrapitops.plan.delivery.webserver.auth.Authentication; import com.djrapitops.plan.delivery.webserver.auth.BasicAuthentication; -import com.djrapitops.plan.delivery.webserver.response.PromptAuthorizationResponse; import com.djrapitops.plan.delivery.webserver.response.ResponseFactory; -import com.djrapitops.plan.delivery.webserver.response.Response_old; -import com.djrapitops.plan.delivery.webserver.response.errors.ForbiddenResponse; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.PluginSettings; import com.djrapitops.plan.settings.config.paths.WebserverSettings; @@ -90,30 +88,30 @@ public class RequestHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) { Headers requestHeaders = exchange.getRequestHeaders(); - Headers responseHeaders = exchange.getResponseHeaders(); RequestInternal request = new RequestInternal(exchange, locale); request.setAuth(getAuthorization(requestHeaders)); try { - Response_old response = shouldPreventRequest(request.getRemoteAddress()) // Forbidden response (Optional) + Response response = shouldPreventRequest(request.getRemoteAddress()) // Forbidden response (Optional) .orElseGet(() -> responseResolver.getResponse(request)); // Or the actual requested response // Increase attempt count and block if too high - Optional forbid = handlePasswordBruteForceAttempts(request, response); + Optional forbid = handlePasswordBruteForceAttempts(request, response); if (forbid.isPresent()) { response = forbid.get(); } // Authentication failed, but was not blocked - if (response instanceof PromptAuthorizationResponse) { - responseHeaders.set("WWW-Authenticate", response.getHeader("WWW-Authenticate").orElse("Basic realm=\"Plan WebUser (/plan register)\"")); - } +// if (response.getCode() == 401) { +//// responseHeaders.set("WWW-Authenticate", Optional.ofNullable(response.getHeaders().get("WWW-Authenticate")).orElse("Basic realm=\"Plan WebUser (/plan register)\"")); +//// } - responseHeaders.set("Access-Control-Allow-Origin", config.get(WebserverSettings.CORS_ALLOW_ORIGIN)); - responseHeaders.set("Access-Control-Allow-Methods", "GET, OPTIONS"); - response.setResponseHeaders(responseHeaders); - response.send(exchange, locale, theme); + response.getHeaders().putIfAbsent("Access-Control-Allow-Origin", config.get(WebserverSettings.CORS_ALLOW_ORIGIN)); + response.getHeaders().putIfAbsent("Access-Control-Allow-Methods", "GET, OPTIONS"); + + ResponseSender sender = new ResponseSender(exchange, response); + sender.send(); } catch (Exception e) { if (config.isTrue(PluginSettings.DEV_MODE)) { logger.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); @@ -124,7 +122,7 @@ public class RequestHandler implements HttpHandler { } } - private Optional shouldPreventRequest(String accessor) { + private Optional shouldPreventRequest(String accessor) { Integer attempts = failedLoginAttempts.getIfPresent(accessor); if (attempts == null) { attempts = 0; @@ -137,8 +135,8 @@ public class RequestHandler implements HttpHandler { return Optional.empty(); } - private Optional handlePasswordBruteForceAttempts(RequestInternal request, Response_old response) { - if (request.getAuth().isPresent() && response instanceof PromptAuthorizationResponse) { + private Optional handlePasswordBruteForceAttempts(RequestInternal request, Response response) { + if (request.getAuth().isPresent() && response.getCode() == 401) { // Authentication was attempted, but failed so new attempt is going to be given if not forbidden failedLoginAttempts.cleanUp(); @@ -158,7 +156,7 @@ public class RequestHandler implements HttpHandler { // Attempts only increased if less than 5 attempts to prevent frustration from the cache value not // getting removed. failedLoginAttempts.put(accessor, attempts + 1); - } else if (!(response instanceof PromptAuthorizationResponse) && !(response instanceof ForbiddenResponse)) { + } else if (response.getCode() != 401 && response.getCode() != 403) { // Successful login failedLoginAttempts.invalidate(request.getRemoteAddress()); } @@ -166,8 +164,8 @@ public class RequestHandler implements HttpHandler { return Optional.empty(); } - private Optional createForbiddenResponse() { - return Optional.of(responseFactory.forbidden403_old("You have too many failed login attempts. Please wait 2 minutes until attempting again.")); + private Optional createForbiddenResponse() { + return Optional.of(responseFactory.forbidden403("You have too many failed login attempts. Please wait 2 minutes until attempting again.")); } private Authentication getAuthorization(Headers requestHeaders) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java index 84b695d86..3d4d7e00a 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseResolver.java @@ -41,6 +41,7 @@ import dagger.Lazy; import javax.inject.Inject; import javax.inject.Singleton; import java.util.Optional; +import java.util.regex.Pattern; /** * Resolves All URLs. @@ -57,6 +58,7 @@ public class ResponseResolver extends CompositePageResolver { private final PlayersPageResolver playersPageResolver; private final PlayerPageResolver playerPageResolver; private final ServerPageResolver serverPageResolver; + private final RootPageResolver rootPageResolver; private final RootJSONResolver rootJSONResolver; private final ErrorHandler errorHandler; @@ -75,6 +77,7 @@ public class ResponseResolver extends CompositePageResolver { PlayersPageResolver playersPageResolver, PlayerPageResolver playerPageResolver, ServerPageResolver serverPageResolver, + RootPageResolver rootPageResolver, RootJSONResolver rootJSONResolver, ErrorHandler errorHandler @@ -87,6 +90,7 @@ public class ResponseResolver extends CompositePageResolver { this.playersPageResolver = playersPageResolver; this.playerPageResolver = playerPageResolver; this.serverPageResolver = serverPageResolver; + this.rootPageResolver = rootPageResolver; this.rootJSONResolver = rootJSONResolver; this.errorHandler = errorHandler; } @@ -99,9 +103,7 @@ public class ResponseResolver extends CompositePageResolver { resolverService.registerResolver(pluginName, "/favicon.ico", noAuthResolverFor(responseFactory.faviconResponse())); resolverService.registerResolver(pluginName, "/network", serverPageResolver); resolverService.registerResolver(pluginName, "/server", serverPageResolver); - - // TODO Figure out how to deal with stuff like this - registerPage("", new RootPageResolver(responseFactory, webServer.get(), serverInfo)); + resolverService.registerResolverForMatches(pluginName, Pattern.compile("^/$"), rootPageResolver); registerPage("v1", rootJSONResolver); } @@ -110,33 +112,33 @@ public class ResponseResolver extends CompositePageResolver { return (request) -> Optional.of(response); } - public Response_old getResponse(RequestInternal request) { + public Response getResponse(RequestInternal request) { try { return tryToGetResponse(request); } catch (NotFoundException e) { - return responseFactory.notFound404_old(e.getMessage()); + return responseFactory.notFound404(e.getMessage()); } catch (WebUserAuthException e) { - return responseFactory.basicAuthFail_old(e); + return responseFactory.basicAuthFail(e); } catch (ForbiddenException e) { - return responseFactory.forbidden403_old(e.getMessage()); + return responseFactory.forbidden403(e.getMessage()); } catch (BadRequestException e) { - return responseFactory.badRequest_old(e.getMessage(), request.getTargetString()); + return responseFactory.badRequest(e.getMessage(), request.getTargetString()); } catch (Exception e) { errorHandler.log(L.ERROR, this.getClass(), e); - return responseFactory.internalErrorResponse_old(e, request.getTargetString()); + return responseFactory.internalErrorResponse(e, request.getTargetString()); } } - private Response_old tryToGetResponse(RequestInternal internalRequest) throws WebException { - if ("OPTIONS".equalsIgnoreCase(internalRequest.getRequestMethod())) { - return new OptionsResponse(); + private Response tryToGetResponse(RequestInternal internalRequest) throws WebException { + if ("OPTIONS" .equalsIgnoreCase(internalRequest.getRequestMethod())) { + return new OptionsResponse().toNewResponse(); } Optional authentication = internalRequest.getAuth(); Optional foundResolver = resolverService.getResolver(internalRequest.getPath().asString()); // TODO Replace with 404 after refactoring - if (!foundResolver.isPresent()) return tryToGetResponse_old(internalRequest); + if (!foundResolver.isPresent()) return tryToGetResponse_old(internalRequest).toNewResponse(); Resolver resolver = foundResolver.get(); @@ -146,19 +148,19 @@ public class ResponseResolver extends CompositePageResolver { boolean isAuthRequired = webServer.get().isAuthRequired(); if (isAuthRequired && !authentication.isPresent()) { if (webServer.get().isUsingHTTPS()) { - return responseFactory.basicAuth_old(); + return responseFactory.basicAuth(); } else { - return responseFactory.forbidden403_old(); + return responseFactory.forbidden403(); } } if (!isAuthRequired || resolver.canAccess(request)) { - return resolver.resolve(request).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old); + return resolver.resolve(request).orElseGet(responseFactory::pageNotFound404); } else { - return responseFactory.forbidden403_old(); + return responseFactory.forbidden403(); } } else { - return resolver.resolve(request).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old); + return resolver.resolve(request).orElseGet(responseFactory::pageNotFound404); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseSender.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseSender.java index 6c4078a1f..a19353850 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseSender.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/ResponseSender.java @@ -50,10 +50,10 @@ public class ResponseSender { } } - public void setResponseHeaders() { + private void setResponseHeaders() { Headers headers = exchange.getResponseHeaders(); for (Map.Entry header : response.getHeaders().entrySet()) { - headers.set(header.getKey(), header.getKey()); + headers.set(header.getKey(), header.getValue()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/pages/RootPageResolver.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/pages/RootPageResolver.java index 71c5ea45d..9df6d4eea 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/pages/RootPageResolver.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/pages/RootPageResolver.java @@ -16,21 +16,19 @@ */ package com.djrapitops.plan.delivery.webserver.pages; -import com.djrapitops.plan.delivery.domain.WebUser_old; import com.djrapitops.plan.delivery.rendering.html.Html; import com.djrapitops.plan.delivery.web.resolver.NoAuthResolver; import com.djrapitops.plan.delivery.web.resolver.Response; import com.djrapitops.plan.delivery.web.resolver.request.Request; -import com.djrapitops.plan.delivery.webserver.RequestInternal; -import com.djrapitops.plan.delivery.webserver.RequestTarget; +import com.djrapitops.plan.delivery.web.resolver.request.WebUser; import com.djrapitops.plan.delivery.webserver.WebServer; -import com.djrapitops.plan.delivery.webserver.auth.Authentication; import com.djrapitops.plan.delivery.webserver.response.ResponseFactory; -import com.djrapitops.plan.delivery.webserver.response.Response_old; -import com.djrapitops.plan.exceptions.connection.WebException; import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.ServerInfo; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Optional; /** @@ -38,13 +36,15 @@ import java.util.Optional; * * @author Rsl1122 */ -public class RootPageResolver implements PageResolver, NoAuthResolver { +@Singleton +public class RootPageResolver implements NoAuthResolver { private final ResponseFactory responseFactory; - private final WebServer webServer; + private final Lazy webServer; private final ServerInfo serverInfo; - public RootPageResolver(ResponseFactory responseFactory, WebServer webServer, ServerInfo serverInfo) { + @Inject + public RootPageResolver(ResponseFactory responseFactory, Lazy webServer, ServerInfo serverInfo) { this.responseFactory = responseFactory; this.webServer = webServer; this.serverInfo = serverInfo; @@ -52,38 +52,31 @@ public class RootPageResolver implements PageResolver, NoAuthResolver { @Override public Optional resolve(Request request) { - return Optional.empty(); + return Optional.of(getResponse(request)); } - @Override - public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException { + private Response getResponse(Request request) { Server server = serverInfo.getServer(); - if (!webServer.isAuthRequired()) { - return responseFactory.redirectResponse_old(server.isProxy() ? "network" : "server/" + Html.encodeToURL(server.getIdentifiableName())); + if (!webServer.get().isAuthRequired()) { + String redirectTo = server.isProxy() ? "network" : "server/" + Html.encodeToURL(server.getIdentifiableName()); + return responseFactory.redirectResponse(redirectTo); } - Optional auth = request.getAuth(); - if (!auth.isPresent()) { - return responseFactory.basicAuth_old(); + Optional webUser = request.getUser(); + if (!webUser.isPresent()) { + return responseFactory.basicAuth(); } - WebUser_old webUser = auth.get().getWebUser(); + WebUser user = webUser.get(); - int permLevel = webUser.getPermLevel(); - switch (permLevel) { - case 0: - return responseFactory.redirectResponse_old(server.isProxy() ? "network" : "server/" + Html.encodeToURL(server.getIdentifiableName())); - case 1: - return responseFactory.redirectResponse_old("players"); - case 2: - return responseFactory.redirectResponse_old("player/" + Html.encodeToURL(webUser.getName())); - default: - return responseFactory.forbidden403_old(); + if (user.hasPermission("page.server")) { + return responseFactory.redirectResponse(server.isProxy() ? "network" : "server/" + Html.encodeToURL(server.getIdentifiableName())); + } else if (user.hasPermission("page.players")) { + return responseFactory.redirectResponse("players"); + } else if (user.hasPermission("page.player.self")) { + return responseFactory.redirectResponse("player/" + Html.encodeToURL(user.getName())); + } else { + return responseFactory.forbidden403(user.getName() + " has insufficient permissions to be redirected to any page. Needs one of: 'page.server', 'page.players' or 'page.player.self'"); } } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) { - return true; - } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/ResponseFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/ResponseFactory.java index 735442319..89890eb8d 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/ResponseFactory.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/ResponseFactory.java @@ -17,11 +17,17 @@ package com.djrapitops.plan.delivery.webserver.response; import com.djrapitops.plan.delivery.domain.container.PlayerContainer; +import com.djrapitops.plan.delivery.rendering.html.icon.Family; +import com.djrapitops.plan.delivery.rendering.html.icon.Icon; import com.djrapitops.plan.delivery.rendering.pages.Page; import com.djrapitops.plan.delivery.rendering.pages.PageFactory; import com.djrapitops.plan.delivery.web.resolver.MimeType; import com.djrapitops.plan.delivery.web.resolver.Response; -import com.djrapitops.plan.delivery.webserver.response.errors.*; +import com.djrapitops.plan.delivery.webserver.auth.FailReason; +import com.djrapitops.plan.delivery.webserver.response.errors.ErrorResponse; +import com.djrapitops.plan.delivery.webserver.response.errors.ForbiddenResponse; +import com.djrapitops.plan.delivery.webserver.response.errors.InternalErrorResponse; +import com.djrapitops.plan.delivery.webserver.response.errors.NotFoundResponse; import com.djrapitops.plan.delivery.webserver.response.pages.RawDataResponse; import com.djrapitops.plan.exceptions.WebUserAuthException; import com.djrapitops.plan.exceptions.connection.NotFoundException; @@ -36,6 +42,8 @@ import com.djrapitops.plan.version.VersionCheckSystem; import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -137,6 +145,10 @@ public class ResponseFactory { } } + public Response internalErrorResponse(Throwable e, String s) { + return forInternalError(e, s); + } + public Response networkPageResponse() { Optional error = checkDbClosedError(); if (error.isPresent()) return error.get(); @@ -205,17 +217,6 @@ public class ResponseFactory { return new ByteResponse(type, FileResponse.format(fileName), files); } - /** - * Redirect somewhere - * - * @param location Starts with '/' - * @return Redirection response. - */ - @Deprecated - public Response_old redirectResponse_old(String location) { - return new RedirectResponse(location); - } - public Response redirectResponse(String location) { return Response.builder().redirectTo(location).build(); } @@ -236,6 +237,10 @@ public class ResponseFactory { return notFound404_old(locale.getString(ErrorPageLang.UNKNOWN_PAGE_404)); } + public Response pageNotFound404() { + return notFound404(locale.getString(ErrorPageLang.UNKNOWN_PAGE_404)); + } + public Response uuidNotFound404() { return notFound404(locale.getString(ErrorPageLang.UUID_404)); } @@ -257,7 +262,7 @@ public class ResponseFactory { try { return Response.builder() .setMimeType(MimeType.HTML) - .setContent(pageFactory.errorPage("404 " + message, message).toHtml()) + .setContent(pageFactory.errorPage(Icon.called("map-signs").build(), "404 " + message, message).toHtml()) .setStatus(404) .build(); } catch (IOException e) { @@ -265,15 +270,49 @@ public class ResponseFactory { } } - @Deprecated - public ErrorResponse basicAuthFail_old(WebUserAuthException e) { + public Response basicAuthFail(WebUserAuthException e) { try { - return PromptAuthorizationResponse.getBasicAuthResponse(e, versionCheckSystem, files); + FailReason failReason = e.getFailReason(); + String reason = failReason.getReason(); + if (failReason == FailReason.ERROR) { + StringBuilder errorBuilder = new StringBuilder("

");
+                for (String line : getStackTrace(e.getCause())) {
+                    errorBuilder.append(line);
+                }
+                errorBuilder.append("
"); + + reason += errorBuilder.toString(); + } + return Response.builder() + .setMimeType(MimeType.HTML) + .setContent(pageFactory.errorPage(Icon.called("lock").build(), "401 Unauthorized", "Authentication Failed.

Reason: " + reason + "

").toHtml()) + .setStatus(401) + .setHeader("WWW-Authenticate", "Basic realm=\"" + failReason.getReason() + "\"") + .build(); } catch (IOException jarReadFailed) { - return internalErrorResponse_old(e, "Failed to generate PromptAuthorizationResponse"); + return forInternalError(e, "Failed to generate PromptAuthorizationResponse"); } } + private 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; + } + @Deprecated public ErrorResponse forbidden403_old() { return forbidden403_old("Your user is not authorized to view this page.
" @@ -289,7 +328,7 @@ public class ResponseFactory { try { return Response.builder() .setMimeType(MimeType.HTML) - .setContent(pageFactory.errorPage("403 Forbidden", message).toHtml()) + .setContent(pageFactory.errorPage(Icon.called("hand-paper").of(Family.REGULAR).build(), "403 Forbidden", message).toHtml()) .setStatus(403) .build(); } catch (IOException e) { @@ -315,9 +354,29 @@ public class ResponseFactory { } } - @Deprecated - public BadRequestResponse badRequest_old(String errorMessage, String target) { - return new BadRequestResponse(errorMessage + " (when requesting '" + target + "')"); + public Response basicAuth() { + try { + String tips = "
- 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."; + return Response.builder() + .setMimeType(MimeType.HTML) + .setContent(pageFactory.errorPage(Icon.called("lock").build(), "401 Unauthorized", "Authentication Failed." + tips).toHtml()) + .setStatus(401) + .setHeader("WWW-Authenticate", "Basic realm=\"Plan WebUser (/plan register)\"") + .build(); + } catch (IOException e) { + return forInternalError(e, "Failed to generate PromptAuthorizationResponse"); + } + } + + public Response badRequest(String errorMessage, String target) { + return Response.builder() + .setMimeType(MimeType.HTML) + .setContent("400 Bad Request: " + errorMessage + " (when requesting '" + target + "')") + .setStatus(400) + .build(); } public Response playerPageResponse(UUID playerUUID) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/Response_old.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/Response_old.java index 34195a5a9..e30d3f7e9 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/Response_old.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/response/Response_old.java @@ -16,6 +16,7 @@ */ package com.djrapitops.plan.delivery.webserver.response; +import com.djrapitops.plan.delivery.web.resolver.Response; import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.theme.Theme; import com.sun.net.httpserver.Headers; @@ -25,7 +26,6 @@ import org.apache.commons.lang3.StringUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.Function; @@ -96,20 +96,12 @@ public abstract class Response_old { return getHeader(null).map(h -> Integer.parseInt(StringUtils.split(h, ' ')[1])).orElse(500); } - @Deprecated - public static Response_old from(com.djrapitops.plan.delivery.web.resolver.Response apiResponse) { - Response_old response = new Response_old() {}; - response.setContent(apiResponse.getCharset().map(charset -> new String(apiResponse.getBytes(), charset)) - .orElse(new String(apiResponse.getBytes()))); - response.setHeader("HTTP/1.1 " + apiResponse.getCode() + " "); - for (Map.Entry header : apiResponse.getHeaders().entrySet()) { - if (header.getKey().equals("Content-Type")) { - response.type = header.getValue(); - continue; - } - response.header += header.getKey() + ": " + header.getValue() + ";\r\n"; - } - return response; + public Response toNewResponse() { + return Response.builder() + .setStatus(getCode()) + .setMimeType(type) + .setContent(content) + .build(); } @Override