mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-30 13:08:00 +01:00
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:
parent
4a1234f9b4
commit
6ed6dd1f9f
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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])
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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."));
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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)))
|
||||
|
@ -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)));
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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, () ->
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user