/*
* Created on 15.03.2005
*/
package jplagWebService.serverAccess;
import java.util.Date;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.Detail;
import javax.xml.soap.DetailEntry;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import jplagWebService.serverImpl.JPlagCentral;
/**
* @author Moritz Kroll
*/
public class JPlagServerAccessHandler extends GenericHandler {
private static final String JPLAG_WEBSERVICE_BASE_URL = "http://jplag.ipd.kit.edu/";
public static final int compatibilityLevel = 4;
protected HandlerInfo info = null;
public QName[] getHeaders() {
return info.getHeaders();
}
public void init(HandlerInfo arg) {
info = arg;
}
/**
* Extracts the username out of the header of a SOAP message
*/
public static String extractUsername(SOAPMessageContext smsg) {
try {
SOAPHeader header = smsg.getMessage().getSOAPHeader();
if (header != null) {
@SuppressWarnings("unchecked")
Iterator<SOAPHeaderElement> headers = header.examineAllHeaderElements();
while (headers.hasNext()) {
SOAPHeaderElement he = headers.next();
if (he.getElementName().getLocalName().equals("Access")) {
@SuppressWarnings("unchecked")
Iterator<SOAPElement> elements = he.getChildElements();
while (elements.hasNext()) {
SOAPElement e = elements.next();
String name = e.getElementName().getLocalName();
if (name.equals("username"))
return e.getValue();
}
}
}
}
} catch (SOAPException x) {
x.printStackTrace();
}
return null;
}
/**
* Manually builds up a JPlagException SOAP message and replaces the
* original one with it
*/
public void replaceByJPlagException(SOAPMessageContext smsg, String desc, String rep) {
try {
SOAPMessage msg = smsg.getMessage();
SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
/*
* Remove old header andy body
*/
SOAPHeader oldheader = envelope.getHeader();
if (oldheader != null)
oldheader.detachNode();
SOAPBody oldbody = envelope.getBody();
if (oldbody != null)
oldbody.detachNode();
SOAPBody sb = envelope.addBody();
SOAPFault sf = sb.addFault(envelope.createName("Server", "env", SOAPConstants.URI_NS_SOAP_ENVELOPE),
"jplagWebService.server.JPlagException");
Detail detail = sf.addDetail();
DetailEntry de = detail.addDetailEntry(envelope.createName("JPlagException", "ns0", JPLAG_WEBSERVICE_BASE_URL + "types"));
SOAPElement e = de.addChildElement("exceptionType");
e.addTextNode("accessException");
e = de.addChildElement("description");
e.addTextNode(desc);
e = de.addChildElement("repair");
e.addTextNode(rep);
} catch (SOAPException x) {
x.printStackTrace();
}
}
/**
* Checks whether the SOAP message contains a valid Access element (correct
* username + password) and whether the account may still be used
*/
public boolean handleRequest(MessageContext context) {
String username = null;
String password = null;
int compatLevel = 0;
if (context instanceof SOAPMessageContext) {
SOAPMessageContext smsg = (SOAPMessageContext) context;
/*
* Iterator iter = context.getPropertyNames();
* System.out.println("Context properties:"); while(iter.hasNext())
* { String propname = (String) iter.next();
* System.out.println(propname + " = " +
* context.getProperty(propname).toString()); }
*
* HttpServletRequest request = (HttpServletRequest)
* context.getProperty(
* "com.sun.xml.rpc.server.http.HttpServletRequest");
* System.out.println("Client IP: " + request.getRemoteAddr());
*/
try {
SOAPHeader header = smsg.getMessage().getSOAPHeader();
if (header != null) {
@SuppressWarnings("unchecked")
Iterator<SOAPHeaderElement> headers = header.examineAllHeaderElements();
while (headers.hasNext()) {
SOAPHeaderElement he = headers.next();
if (he.getElementName().getLocalName().equals("Access")) {
@SuppressWarnings("unchecked")
Iterator<SOAPElement> elements = he.getChildElements();
while (elements.hasNext()) {
SOAPElement e = elements.next();
String name = e.getElementName().getLocalName();
if (name.equals("username"))
username = e.getValue();
else if (name.equals("password"))
password = e.getValue();
else if (name.equals("compatLevel")) {
try {
compatLevel = Integer.parseInt(e.getValue());
} catch (NumberFormatException ex) {
compatLevel = -1;
}
}
}
}
}
if (compatLevel < compatibilityLevel) {
replaceByJPlagException(smsg, "Client outdated!", "Please update your client " + "to compatibility level "
+ compatibilityLevel + ".");
return false;
}
if (username != null && password != null) {
int state = JPlagCentral.getInstance().getUserAdmin().getLoginState(username, password);
if ((state & UserAdmin.MASK_EXPIRED) != 0) {
replaceByJPlagException(smsg, "Access denied!", "Your account has " + "expired! Please contact the JPlag "
+ "administrator to reactivate it!");
return false;
} else if ((state & UserAdmin.MASK_DEACTIVATED) != 0) {
replaceByJPlagException(smsg, "Access denied!", "Your account has " + "been deactivated! Please contact the "
+ "JPlag administrator to reactivate it!");
return false;
} else if (state != UserAdmin.USER_INVALID)
return true;
}
} else {
System.out.println("No header available!");
replaceByJPlagException(smsg, "Access denied!", "The SOAP message doesn't contain an access header!");
return false;
}
} catch (SOAPException x) {
x.printStackTrace();
}
System.out.println("[" + new Date() + "] Access denied for user \"" + username + "\"!");
replaceByJPlagException(smsg, "Access denied!", "Check your username and password!");
return false;
}
System.out.println("Not a SOAP message context!!!");
return false;
}
}