Add part of client authorization
This commit is contained in:
@@ -4,6 +4,6 @@ import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Intercept {
|
||||
String allowedMethods() default "GET";
|
||||
public @interface AllowedVerb {
|
||||
String name() default "GET";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package httpsServer.httpServer.src.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface OnlyAuthorizedClients {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package httpsServer.httpServer.src.exceptions;
|
||||
|
||||
public class ClientAuthorisationException extends Exception {
|
||||
|
||||
public ClientAuthorisationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package httpsServer.httpServer.src.exceptions;
|
||||
|
||||
public class NoSuchVerbException extends Exception {
|
||||
|
||||
public NoSuchVerbException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import common.common.src.html.HtmlManager;
|
||||
import common.common.src.logger.Logger;
|
||||
import httpsServer.httpServer.src.annotations.Intercept;
|
||||
import httpsServer.httpServer.src.annotations.AllowedVerb;
|
||||
import httpsServer.httpServer.src.annotations.OnlyAuthorizedClients;
|
||||
import httpsServer.httpServer.src.authorization.AuthorizedClients;
|
||||
import httpsServer.httpServer.src.authorization.Client;
|
||||
|
||||
@@ -15,7 +16,7 @@ public class RequestHandler implements IRequestHandler {
|
||||
|
||||
final AuthorizedClients authorizedClients = new AuthorizedClients();
|
||||
|
||||
@Intercept(allowedMethods = "GET")
|
||||
@AllowedVerb(name = "GET")
|
||||
public void handleRoot(HttpExchange exchange) {
|
||||
try{
|
||||
respondToGet(exchange, "./assets/pages/index.html");
|
||||
@@ -24,7 +25,8 @@ public class RequestHandler implements IRequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Intercept(allowedMethods = "GET")
|
||||
@AllowedVerb(name = "GET")
|
||||
@OnlyAuthorizedClients
|
||||
public void handlePayment(HttpExchange exchange) {
|
||||
Logger.displayReceived("/payment request");
|
||||
try{
|
||||
@@ -34,7 +36,7 @@ public class RequestHandler implements IRequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Intercept(allowedMethods = "POST")
|
||||
@AllowedVerb(name = "POST")
|
||||
public void handleLogin(HttpExchange exchange) {
|
||||
try {
|
||||
InputStream is = exchange.getRequestBody();
|
||||
@@ -58,6 +60,7 @@ public class RequestHandler implements IRequestHandler {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void respondToGet(HttpExchange exchange, String pagePath) throws IOException {
|
||||
|
||||
try{
|
||||
|
||||
@@ -1,45 +1,82 @@
|
||||
package httpsServer.httpServer.src.interceptors;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import common.common.src.logger.Logger;
|
||||
import httpsServer.httpServer.src.annotations.Intercept;
|
||||
import httpsServer.httpServer.src.annotations.AllowedVerb;
|
||||
import httpsServer.httpServer.src.annotations.OnlyAuthorizedClients;
|
||||
import httpsServer.httpServer.src.authorization.AuthorizedClients;
|
||||
import httpsServer.httpServer.src.authorization.Client;
|
||||
import httpsServer.httpServer.src.exceptions.NoSuchVerbException;
|
||||
import httpsServer.httpServer.src.exceptions.ClientAuthorisationException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class RequestInterceptor implements InvocationHandler {
|
||||
|
||||
private final AuthorizedClients authorizedClients;
|
||||
private final ObjectMapper mapper;
|
||||
private final Object target;
|
||||
|
||||
public RequestInterceptor(Object target) {
|
||||
authorizedClients = new AuthorizedClients();
|
||||
mapper = new ObjectMapper();
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
HttpExchange exchange = (HttpExchange) args[0];
|
||||
try{
|
||||
Method realMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());
|
||||
|
||||
Method realMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());
|
||||
if (!realMethod.isAnnotationPresent(Intercept.class)) return null;
|
||||
checkAuthorizedVerb(realMethod, exchange.getRequestMethod());
|
||||
//String a = exchange.getRequestHeaders().getFirst("Header-Name");
|
||||
checkAuthorizedClient(realMethod, exchange.getRequestBody());
|
||||
|
||||
Logger.displayReceived("/ request");
|
||||
|
||||
HttpExchange exchange = (HttpExchange)args[0];
|
||||
|
||||
Intercept annotation = realMethod.getAnnotation(Intercept.class);
|
||||
String allowedVerb = annotation.allowedMethods();
|
||||
String receivedVerb = exchange.getRequestMethod();
|
||||
|
||||
if(isAuthorizedVerb(allowedVerb, receivedVerb)) {
|
||||
return method.invoke(target, args);
|
||||
} else {
|
||||
exchange.sendResponseHeaders(405, -1);
|
||||
exchange.getResponseBody().close();
|
||||
|
||||
} catch (NoSuchVerbException e) {
|
||||
closeExchangeWithCode(exchange, 405);
|
||||
return null;
|
||||
} catch (ClientAuthorisationException e) {
|
||||
closeExchangeWithCode(exchange, 401);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isAuthorizedVerb(String baseVerb, String receivedVerb) {
|
||||
return baseVerb.equalsIgnoreCase(receivedVerb);
|
||||
private void closeExchangeWithCode(HttpExchange exchange, int httpCode) throws IOException {
|
||||
exchange.sendResponseHeaders(httpCode, -1);
|
||||
exchange.getResponseBody().close();
|
||||
}
|
||||
|
||||
private void checkAuthorizedVerb(Method method, String receivedVerb) throws NoSuchVerbException {
|
||||
if (!method.isAnnotationPresent(AllowedVerb.class)) return;
|
||||
|
||||
String allowedVerb = method.getAnnotation(AllowedVerb.class).name();
|
||||
if(!allowedVerb.equalsIgnoreCase(receivedVerb)){
|
||||
throw new NoSuchVerbException("HTTP verb not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAuthorizedClient(Method method, InputStream data) throws ClientAuthorisationException {
|
||||
if (!method.isAnnotationPresent(OnlyAuthorizedClients.class)) return;
|
||||
|
||||
Client client = null;
|
||||
try(BufferedReader reader = new BufferedReader(new InputStreamReader(data, StandardCharsets.UTF_8))){
|
||||
String body = reader.lines().reduce("", (acc, line) -> acc + line + "\n");
|
||||
client = mapper.readValue(body, Client.class);
|
||||
} catch (IOException e){
|
||||
throw new ClientAuthorisationException("Unable to read body");
|
||||
}
|
||||
|
||||
if(!authorizedClients.isAuthorized(client)){
|
||||
throw new ClientAuthorisationException("Client not authorized");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user