Refactored Resolver to use new Request class

URIPath and URIQuery were not enough info on the Request
In addition the Request supports
- WebUser
- Request Headers
- Request method (GET, POST etc)
This commit is contained in:
Rsl1122 2020-02-16 18:18:14 +02:00 committed by Risto Lahtela
parent 4a1234f9b4
commit 6ed6dd1f9f
30 changed files with 384 additions and 89 deletions

View File

@ -16,6 +16,9 @@
*/
package com.djrapitops.plan.delivery.web.resolver;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@ -63,16 +66,16 @@ public final class CompositeResolver implements Resolver {
}
@Override
public boolean canAccess(WebUser permissions, URIPath target, URIQuery query) {
return getResolver(target)
.map(resolver -> resolver.canAccess(permissions, target.omitFirst(), query))
public boolean canAccess(Request request) {
return getResolver(request.getPath())
.map(resolver -> resolver.canAccess(request))
.orElse(true);
}
@Override
public Optional<Response> resolve(URIPath target, URIQuery query) {
return getResolver(target)
.flatMap(resolver -> resolver.resolve(target.omitFirst(), query));
public Optional<Response> resolve(Request request) {
return getResolver(request.getPath())
.flatMap(resolver -> resolver.resolve(request));
}
public static class Builder {

View File

@ -16,6 +16,8 @@
*/
package com.djrapitops.plan.delivery.web.resolver;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import java.util.Optional;
/**
@ -25,25 +27,24 @@ import java.util.Optional;
*/
public interface NoAuthResolver extends Resolver {
default boolean canAccess(WebUser permissions, URIPath target, URIQuery query) {
default boolean canAccess(Request request) {
return true;
}
/**
* Implement request resolution.
*
* @param target Target that is being accessed, /example/target
* @param query Parameters in the URL, ?param=value etc.
* @param request HTTP request, contains all information necessary to resolve the request.
* @return Response or empty if the response should be 404 (not found).
* @see Response for return value
*/
Optional<Response> resolve(URIPath target, URIQuery query);
Optional<Response> resolve(Request request);
default ResponseBuilder newResponseBuilder() {
return Response.builder();
}
default boolean requiresAuth(URIPath target, URIQuery query) {
default boolean requiresAuth(Request request) {
return false;
}
}

View File

@ -16,6 +16,9 @@
*/
package com.djrapitops.plan.delivery.web.resolver;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import java.util.Optional;
/**
@ -31,28 +34,28 @@ public interface Resolver {
* <p>
* Is not called when access control is not active.
*
* @param permissions WebUser that is accessing this page.
* @param target Target that is being accessed, /example/target
* @param query Parameters in the URL, ?param=value etc.
* @param request HTTP request, contains all information necessary to check access.
* @return true if allowed or invalid target, false if response should be 403 (forbidden)
* @see Request#getUser() for {@link WebUser} that has access permissions.
*/
boolean canAccess(WebUser permissions, URIPath target, URIQuery query);
boolean canAccess(Request request);
/**
* Implement request resolution.
*
* @param target Target that is being accessed, /example/target
* @param query Parameters in the URL, ?param=value etc.
* @param request HTTP request, contains all information necessary to resolve the request.
* @return Response or empty if the response should be 404 (not found).
* @see Response for return value
* @see Request#getPath() for path /example/path etc
* @see Request#getQuery() for parameters ?param=value etc
*/
Optional<Response> resolve(URIPath target, URIQuery query);
Optional<Response> resolve(Request request);
default ResponseBuilder newResponseBuilder() {
return Response.builder();
}
default boolean requiresAuth(URIPath target, URIQuery query) {
default boolean requiresAuth(Request request) {
return true;
}
}

View File

@ -0,0 +1,22 @@
package com.djrapitops.plan.delivery.web.resolver.request;
import java.util.Map;
import java.util.Optional;
/**
* Request headers, read only.
*
* @author Rsl1122
*/
public class Headers {
private final Map<String, String> headers;
public Headers(Map<String, String> headers) {
this.headers = headers;
}
private Optional<String> get(String key) {
return Optional.ofNullable(headers.get(key));
}
}

View File

@ -0,0 +1,99 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.web.resolver.request;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import java.util.Map;
import java.util.Optional;
/**
* Represents a HTTP request to use with {@link Resolver}.
*
* @author Rsl1122
*/
public final class Request {
private final String method;
private final URIPath path;
private final URIQuery query;
private final WebUser user;
private final Map<String, String> headers;
/**
* Constructor.
*
* @param method HTTP method, GET, PUT, POST, etc
* @param path Requested path /example/target
* @param query Request parameters ?param=value etc
* @param user Web user doing the request (if authenticated)
* @param headers Request headers https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
*/
public Request(String method, URIPath path, URIQuery query, WebUser user, Map<String, String> headers) {
this.method = method;
this.path = path;
this.query = query;
this.user = user;
this.headers = headers;
}
/**
* Get HTTP method.
*
* @return GET, PUT, POST, etc
*/
public String getMethod() {
return method;
}
/**
* Get the Requested path.
*
* @return {@link URIPath}.
*/
public URIPath getPath() {
return path;
}
/**
* Get the Request parameters.
*
* @return {@link URIQuery}.
*/
public URIQuery getQuery() {
return query;
}
/**
* Get the user making the request.
*
* @return the user if authentication is enabled
*/
public Optional<WebUser> getUser() {
return Optional.ofNullable(user);
}
/**
* Get a header in the request.
*
* @param key https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
* @return Value if it is present in the request.
*/
public Optional<String> getHeader(String key) {
return Optional.ofNullable(headers.get(key));
}
}

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.web.resolver;
package com.djrapitops.plan.delivery.web.resolver.request;
import java.util.Optional;

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.web.resolver;
package com.djrapitops.plan.delivery.web.resolver.request;
import org.apache.commons.lang3.StringUtils;

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.web.resolver;
package com.djrapitops.plan.delivery.web.resolver.request;
import java.util.Arrays;
import java.util.HashSet;

View File

@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.delivery.web.resolver;
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

View File

@ -16,6 +16,8 @@
*/
package com.djrapitops.plan.delivery.domain;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -65,7 +67,7 @@ public class WebUser_old {
return Objects.hash(user, saltedPassHash, permLevel);
}
public com.djrapitops.plan.delivery.web.resolver.WebUser toNewWebUser() {
public WebUser toNewWebUser() {
List<String> permissions = new ArrayList<>();
if (permLevel <= 0) {
permissions.add("page.network");
@ -80,7 +82,7 @@ public class WebUser_old {
if (permLevel <= 2) {
permissions.add("page.player.self");
}
return new com.djrapitops.plan.delivery.web.resolver.WebUser(
return new WebUser(
user, permissions.toArray(new String[0])
);
}

View File

@ -43,6 +43,8 @@ import java.util.*;
/**
* Factory for creating different {@link Page} objects.
* <p>
* TODO Set theme and locale stuff in here
*
* @author Rsl1122
*/

View File

@ -92,7 +92,7 @@ public class RequestHandler implements HttpHandler {
Headers requestHeaders = exchange.getRequestHeaders();
Headers responseHeaders = exchange.getResponseHeaders();
Request request = new Request(exchange, locale);
RequestInternal request = new RequestInternal(exchange, locale);
request.setAuth(getAuthorization(requestHeaders));
try {
@ -137,7 +137,7 @@ public class RequestHandler implements HttpHandler {
return Optional.empty();
}
private Optional<Response_old> handlePasswordBruteForceAttempts(Request request, Response_old response) {
private Optional<Response_old> handlePasswordBruteForceAttempts(RequestInternal request, Response_old response) {
if (request.getAuth().isPresent() && response instanceof PromptAuthorizationResponse) {
// Authentication was attempted, but failed so new attempt is going to be given if not forbidden

View File

@ -16,14 +16,20 @@
*/
package com.djrapitops.plan.delivery.webserver;
import com.djrapitops.plan.delivery.web.resolver.URIPath;
import com.djrapitops.plan.delivery.web.resolver.URIQuery;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
import com.djrapitops.plan.delivery.web.resolver.request.URIQuery;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.settings.locale.Locale;
import com.sun.net.httpserver.HttpExchange;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
@ -33,7 +39,7 @@ import java.util.Optional;
*
* @author Rsl1122
*/
public class Request {
public class RequestInternal {
private final String requestMethod;
private final URI requestURI;
@ -43,7 +49,7 @@ public class Request {
private final Locale locale;
private Authentication auth;
public Request(HttpExchange exchange, Locale locale) {
public RequestInternal(HttpExchange exchange, Locale locale) {
this.requestMethod = exchange.getRequestMethod();
requestURI = exchange.getRequestURI();
@ -99,4 +105,28 @@ public class Request {
public RequestTarget getRequestTarget() {
return new RequestTarget(requestURI);
}
public Request toAPIRequest() throws WebUserAuthException {
return new Request(
requestMethod,
getPath(),
getQuery(),
getWebUser(),
getRequestHeaders()
);
}
private WebUser getWebUser() throws WebUserAuthException {
Optional<Authentication> auth = getAuth();
return auth.isPresent() ? auth.get().getWebUser().toNewWebUser() : null;
}
private Map<String, String> getRequestHeaders() {
Map<String, String> headers = new HashMap<>();
for (Map.Entry<String, List<String>> e : exchange.getResponseHeaders().entrySet()) {
List<String> value = e.getValue();
headers.put(e.getKey(), value.toString().substring(0, value.size() - 1));
}
return headers;
}
}

View File

@ -18,7 +18,10 @@ package com.djrapitops.plan.delivery.webserver;
import com.djrapitops.plan.delivery.web.ResolverService;
import com.djrapitops.plan.delivery.web.ResolverSvc;
import com.djrapitops.plan.delivery.web.resolver.*;
import com.djrapitops.plan.delivery.web.resolver.NoAuthResolver;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.pages.*;
import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONResolver;
@ -104,10 +107,10 @@ public class ResponseResolver extends CompositePageResolver {
}
public NoAuthResolver noAuthResolverFor(Response response) {
return (target, query) -> Optional.of(response);
return (request) -> Optional.of(response);
}
public Response_old getResponse(Request request) {
public Response_old getResponse(RequestInternal request) {
try {
return tryToGetResponse(request);
} catch (NotFoundException e) {
@ -124,22 +127,21 @@ public class ResponseResolver extends CompositePageResolver {
}
}
private Response_old tryToGetResponse(Request request) throws WebException {
if ("OPTIONS".equalsIgnoreCase(request.getRequestMethod())) {
private Response_old tryToGetResponse(RequestInternal internalRequest) throws WebException {
if ("OPTIONS".equalsIgnoreCase(internalRequest.getRequestMethod())) {
return new OptionsResponse();
}
Optional<Authentication> authentication = request.getAuth();
Optional<Authentication> authentication = internalRequest.getAuth();
URIPath target = request.getPath();
URIQuery query = request.getQuery();
Optional<Resolver> foundResolver = resolverService.getResolver(target.asString());
if (!foundResolver.isPresent()) return tryToGetResponse_old(request); // TODO Replace with 404 after refactoring
Optional<Resolver> foundResolver = resolverService.getResolver(internalRequest.getPath().asString());
// TODO Replace with 404 after refactoring
if (!foundResolver.isPresent()) return tryToGetResponse_old(internalRequest);
Resolver resolver = foundResolver.get();
if (resolver.requiresAuth(target, query)) {
Request request = internalRequest.toAPIRequest();
if (resolver.requiresAuth(request)) {
// Get required auth
boolean isAuthRequired = webServer.get().isAuthRequired();
if (isAuthRequired && !authentication.isPresent()) {
@ -150,17 +152,17 @@ public class ResponseResolver extends CompositePageResolver {
}
}
if (!isAuthRequired || resolver.canAccess(authentication.get().getWebUser().toNewWebUser(), target, query)) {
return resolver.resolve(target, query).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old);
if (!isAuthRequired || resolver.canAccess(request)) {
return resolver.resolve(request).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old);
} else {
return responseFactory.forbidden403_old();
}
} else {
return resolver.resolve(target, query).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old);
return resolver.resolve(request).map(Response_old::from).orElseGet(responseFactory::pageNotFound404_old);
}
}
private Response_old tryToGetResponse_old(Request request) throws WebException {
private Response_old tryToGetResponse_old(RequestInternal request) throws WebException {
RequestTarget target = request.getRequestTarget();
Optional<Authentication> authentication = request.getAuth();
String resource = target.getResourceString();

View File

@ -0,0 +1,90 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.webserver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
/**
* Utility for sending a Response to HttpExchange.
*
* @author Rsl1122
*/
public class ResponseSender {
private final HttpExchange exchange;
private final Response response;
public ResponseSender(HttpExchange exchange, Response response) {
this.exchange = exchange;
this.response = response;
}
public void send() throws IOException {
setResponseHeaders();
if ("bytes".equalsIgnoreCase(response.getHeaders().get("Accept-Ranges"))) {
sendRawBytes();
} else {
sendCompressed();
}
}
public void setResponseHeaders() {
Headers headers = exchange.getResponseHeaders();
for (Map.Entry<String, String> header : response.getHeaders().entrySet()) {
headers.set(header.getKey(), header.getKey());
}
}
private void sendCompressed() throws IOException {
exchange.getResponseHeaders().set("Content-Encoding", "gzip");
beginSend();
try (OutputStream out = new GZIPOutputStream(exchange.getResponseBody())) {
send(out);
}
}
private void beginSend() throws IOException {
exchange.sendResponseHeaders(response.getCode(), 0);
}
private void sendRawBytes() throws IOException {
beginSend();
try (OutputStream out = exchange.getResponseBody()) {
send(out);
}
}
private void send(OutputStream out) throws IOException {
try (
ByteArrayInputStream bis = new ByteArrayInputStream(response.getBytes())
) {
byte[] buffer = new byte[2048];
int count;
while ((count = bis.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
}
}
}

View File

@ -16,7 +16,7 @@
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
@ -58,7 +58,7 @@ public abstract class CompositePageResolver implements PageResolver {
public void registerPage(String targetPage, PageResolver resolver, int requiredPerm) {
pages.put(targetPage, new PageResolver() {
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
return resolver.resolve(request, target);
}
@ -73,7 +73,7 @@ public abstract class CompositePageResolver implements PageResolver {
public void registerPage(String targetPage, Response_old response, int requiredPerm) {
pages.put(targetPage, new PageResolver() {
@Override
public Response_old resolve(Request request, RequestTarget target) {
public Response_old resolve(RequestInternal request, RequestTarget target) {
return response;
}
@ -86,7 +86,7 @@ public abstract class CompositePageResolver implements PageResolver {
@Override
@Deprecated
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
PageResolver pageResolver = getPageResolver(target);
return pageResolver != null
? pageResolver.resolve(request, target)

View File

@ -16,7 +16,9 @@
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.web.resolver.*;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import javax.inject.Inject;
@ -39,12 +41,12 @@ public class DebugPageResolver implements Resolver {
}
@Override
public boolean canAccess(WebUser permissions, URIPath target, URIQuery query) {
return permissions.hasPermission("page.debug");
public boolean canAccess(Request request) {
return request.getUser().map(user -> user.hasPermission("page.debug")).orElse(false);
}
@Override
public Optional<Response> resolve(URIPath target, URIQuery query) {
public Optional<Response> resolve(Request request) {
return Optional.of(responseFactory.debugPageResponse());
}
}

View File

@ -16,7 +16,7 @@
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.response.Response_old;
@ -39,7 +39,7 @@ public interface PageResolver {
* @param target Rest of the target coordinates after this page has been solved.
* @return Appropriate response.
*/
Response_old resolve(Request request, RequestTarget target) throws WebException;
Response_old resolve(RequestInternal request, RequestTarget target) throws WebException;
default boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return true;

View File

@ -16,7 +16,11 @@
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.web.resolver.*;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import com.djrapitops.plan.identification.UUIDUtility;
@ -46,21 +50,24 @@ public class PlayerPageResolver implements Resolver {
}
@Override
public boolean canAccess(WebUser user, URIPath target, URIQuery query) {
boolean isOwnPage = target.getPart(1).map(user.getName()::equalsIgnoreCase).orElse(true);
public boolean canAccess(Request request) {
URIPath path = request.getPath();
WebUser user = request.getUser().orElse(new WebUser(""));
boolean isOwnPage = path.getPart(1).map(user.getName()::equalsIgnoreCase).orElse(true);
return user.hasPermission("page.player.other") || (user.hasPermission("page.player.self") && isOwnPage);
}
@Override
public Optional<Response> resolve(URIPath target, URIQuery query) {
Optional<String> part = target.getPart(1);
public Optional<Response> resolve(Request request) {
URIPath path = request.getPath();
Optional<String> part = path.getPart(1);
if (!part.isPresent()) return Optional.empty();
String playerName = part.get();
UUID playerUUID = uuidUtility.getUUIDOf(playerName);
if (playerUUID == null) return Optional.of(responseFactory.uuidNotFound404());
boolean raw = target.getPart(2).map("raw"::equalsIgnoreCase).orElse(false);
boolean raw = path.getPart(2).map("raw"::equalsIgnoreCase).orElse(false);
return Optional.of(
raw ? responseFactory.rawPlayerPageResponse(playerUUID)
: responseFactory.playerPageResponse(playerUUID)

View File

@ -16,7 +16,9 @@
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.web.resolver.*;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import javax.inject.Inject;
@ -41,12 +43,12 @@ public class PlayersPageResolver implements Resolver {
}
@Override
public boolean canAccess(WebUser permissions, URIPath target, URIQuery query) {
return permissions.hasPermission("page.players");
public boolean canAccess(Request request) {
return request.getUser().map(user -> user.hasPermission("page.players")).orElse(false);
}
@Override
public Optional<Response> resolve(URIPath target, URIQuery query) {
public Optional<Response> resolve(Request request) {
return Optional.of(responseFactory.playersPageResponse());
}
}

View File

@ -18,7 +18,10 @@ 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.webserver.Request;
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.webserver.WebServer;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
@ -35,7 +38,7 @@ import java.util.Optional;
*
* @author Rsl1122
*/
public class RootPageResolver implements PageResolver {
public class RootPageResolver implements PageResolver, NoAuthResolver {
private final ResponseFactory responseFactory;
private final WebServer webServer;
@ -48,7 +51,12 @@ public class RootPageResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Optional<Response> resolve(Request request) {
return Optional.empty();
}
@Override
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
Server server = serverInfo.getServer();
if (!webServer.isAuthRequired()) {
return responseFactory.redirectResponse_old(server.isProxy() ? "network" : "server/" + Html.encodeToURL(server.getIdentifiableName()));

View File

@ -17,7 +17,11 @@
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.rendering.html.Html;
import com.djrapitops.plan.delivery.web.resolver.*;
import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import com.djrapitops.plan.delivery.webserver.WebServer;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import com.djrapitops.plan.identification.Server;
@ -58,16 +62,17 @@ public class ServerPageResolver implements Resolver {
}
@Override
public boolean canAccess(WebUser permissions, URIPath target, URIQuery query) {
String firstPart = target.getPart(0).orElse("");
public boolean canAccess(Request request) {
String firstPart = request.getPath().getPart(0).orElse("");
WebUser permissions = request.getUser().orElse(new WebUser(""));
boolean forServerPage = firstPart.equalsIgnoreCase("server") && permissions.hasPermission("page.server");
boolean forNetworkPage = firstPart.equalsIgnoreCase("network") && permissions.hasPermission("page.network");
return forServerPage || forNetworkPage;
}
@Override
public Optional<Response> resolve(URIPath target, URIQuery query) {
return getServerUUID(target)
public Optional<Response> resolve(Request request) {
return getServerUUID(request.getPath())
.map(this::getServerPage)
.orElseGet(this::redirectToCurrentServer);
}

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.graphs.GraphJSONCreator;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -56,7 +56,7 @@ public class GraphsJSONResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
String type = target.getParameter("type")
.orElseThrow(() -> new BadRequestException("'type' parameter was not defined."));

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.network.NetworkTabJSONCreator;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -45,7 +45,7 @@ public class NetworkTabJSONResolver<T> implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) {
public Response_old resolve(RequestInternal request, RequestTarget target) {
return JSONCache.getOrCache(dataID, () -> new JSONResponse(jsonCreator.get()));
}

View File

@ -18,7 +18,7 @@ package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.domain.WebUser_old;
import com.djrapitops.plan.delivery.rendering.json.PlayerJSONCreator;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.pages.PageResolver;
@ -45,7 +45,7 @@ public class PlayerJSONResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
UUID playerUUID = identifiers.getPlayerUUID(target); // Can throw BadRequestException
return new JSONResponse(jsonCreator.createJSONAsMap(playerUUID));
}

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -55,7 +55,7 @@ public class PlayerKillsJSONResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target);
return JSONCache.getOrCache(DataID.KILLS, serverUUID, () ->
new JSONResponse(Collections.singletonMap("player_kills", jsonFactory.serverPlayerKillsAsJSONMap(serverUUID)))

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -54,7 +54,7 @@ public class PlayersTableJSONResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
if (target.getParameter("server").isPresent()) {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return JSONCache.getOrCache(DataID.PLAYERS, serverUUID, () -> new JSONResponse(jsonFactory.serverPlayersTableJSON(serverUUID)));

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.ServerTabJSONCreator;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -54,7 +54,7 @@ public class ServerTabJSONResolver<T> implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return JSONCache.getOrCache(dataID, serverUUID, () -> new JSONResponse(jsonCreator.apply(serverUUID)));
}

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestInternal;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
@ -55,7 +55,7 @@ public class SessionsJSONResolver implements PageResolver {
}
@Override
public Response_old resolve(Request request, RequestTarget target) throws WebException {
public Response_old resolve(RequestInternal request, RequestTarget target) throws WebException {
if (target.getParameter("server").isPresent()) {
UUID serverUUID = identifiers.getServerUUID(target);
return JSONCache.getOrCache(DataID.SESSIONS, serverUUID, () ->

View File

@ -254,7 +254,6 @@ public class ResponseFactory {
}
public Response notFound404(String message) {
try {
return Response.builder()
.setMimeType(MimeType.HTML)
@ -281,6 +280,23 @@ public class ResponseFactory {
+ "If you believe this is an error contact staff to change your access level.");
}
public Response forbidden403() {
return forbidden403("Your user is not authorized to view this page.<br>"
+ "If you believe this is an error contact staff to change your access level.");
}
public Response forbidden403(String message) {
try {
return Response.builder()
.setMimeType(MimeType.HTML)
.setContent(pageFactory.errorPage("403 Forbidden", message).toHtml())
.setStatus(403)
.build();
} catch (IOException e) {
return forInternalError(e, "Failed to generate 403 page");
}
}
@Deprecated
public ErrorResponse forbidden403_old(String message) {
try {