This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/server/src/main/java/envoy/server/net/ObjectMessageProcessor.java

110 lines
3.2 KiB
Java
Executable File

package envoy.server.net;
import java.io.*;
import java.lang.reflect.ParameterizedType;
import java.util.Set;
import java.util.logging.*;
import com.jenkov.nioserver.*;
import com.jenkov.nioserver.Message;
import envoy.data.AuthenticatedRequest;
import envoy.util.EnvoyLog;
import envoy.server.data.*;
import envoy.server.processors.ObjectProcessor;
/**
* Handles incoming objects.
*
* @author Kai S. K. Engelbart
* @since Envoy Server Standalone v0.1-alpha
*/
public final class ObjectMessageProcessor implements IMessageProcessor {
private final Set<ObjectProcessor<?>> processors;
private static final Logger logger = EnvoyLog.getLogger(ObjectMessageProcessor.class);
/**
* The constructor to set the {@link ObjectProcessor}s.
*
* @param processors the {@link ObjectProcessor} to set
* @since Envoy Server Standalone v0.1-alpha
*/
public ObjectMessageProcessor(Set<ObjectProcessor<?>> processors) {
this.processors = processors;
}
@Override
public void process(Message message, WriteProxy writeProxy) {
try (ObjectInputStream in =
new ObjectInputStream(new ByteArrayInputStream(message.sharedArray, message.offset + 4,
message.length - 4))) {
Object obj = in.readObject();
if (obj == null) {
logger.warning("Received a null object");
return;
}
// authenticate requests if necessary
boolean authenticated = false;
if (obj instanceof AuthenticatedRequest) {
Contact contact = PersistenceManager.getInstance()
.getContactByID(((AuthenticatedRequest<?>) obj).getUserID());
// Validating the authenticity of the request
if (contact == null || contact instanceof Group
|| !((AuthenticatedRequest<?>) obj).getAuthentication()
.equals(((User) contact).getAuthToken())) {
// Invalid request
logger.log(Level.INFO,
"A user tried to perform an authenticated request but could not identify himself. Discarding request.");
return;
}
// Valid request
logger.log(Level.INFO, "A user successfully authenticated a request for " + obj);
authenticated = true;
obj = ((AuthenticatedRequest<?>) obj).getRequest();
} else
logger.log(Level.FINE, "Received unauthenticated " + obj);
refer(message.socketId, writeProxy, obj, authenticated);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* Executes the appropriate {@link ObjectProcessor} for the given input ({@code obj}), if any is
* present.
*/
@SuppressWarnings("unchecked")
private void refer(long socketID, WriteProxy writeProxy, Object obj, boolean authenticated) {
// Get processor and input class and process object
for (@SuppressWarnings("rawtypes")
ObjectProcessor p : processors) {
Class<?> c = (Class<?>) ((ParameterizedType) p.getClass().getGenericInterfaces()[0])
.getActualTypeArguments()[0];
if (c.equals(obj.getClass())) {
if (!authenticated && p.isAuthenticationRequired()) {
logger.log(Level.INFO,
"Discarding request as no authentication has been provided");
return;
}
try {
p.process(c.cast(obj), socketID, new ObjectWriteProxy(writeProxy));
break;
} catch (IOException e) {
logger.log(Level.SEVERE, "Exception during processor execution: ", e);
}
}
}
}
}