package com.bansheeproject.features; import java.util.Calendar; import java.util.Iterator; import javax.xml.namespace.QName; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import org.w3c.dom.Node; import com.bansheeproject.SOAPInvocationData; import com.bansheeproject.WebServicesInvocationData; import com.bansheeproject.engine.InvocationContext; import com.bansheeproject.exceptions.InstallFeatureException; import com.bansheeproject.utils.DateTimeUtils; import com.bansheeproject.utils.TimeUnit; /** * Places timestamps over SOAP requests. * * @author Alexandre Saudate * @since 1.0 */ public class WSTimestampFeature implements WSSecurityFeature{ private long modifier; private TimeUnit unit; private String timestampId; private boolean mustUnderstand; public WSTimestampFeature(long modifier, TimeUnit unit) { this(modifier, unit, "Timestamp-1"); } public WSTimestampFeature(long modifier, TimeUnit unit, String timestampId) { this(modifier, unit, timestampId, false); } public WSTimestampFeature(long modifier, TimeUnit unit, String timestampId, boolean mustUnderstand) { if (modifier <= 0) { throw new IllegalArgumentException("Interval cannot be lower or equal than zero."); } if (unit == null) { throw new IllegalArgumentException("Time unit cannot be null."); } this.timestampId = timestampId; this.modifier = modifier; this.unit = unit; this.mustUnderstand = mustUnderstand; } public void install(InvocationContext context) throws InstallFeatureException { try { WebServicesInvocationData webServicesInvocationData = context.getInvocationData(); if (!(webServicesInvocationData instanceof SOAPInvocationData)) { throw new InstallFeatureException("This feature can only be added to a SOAP environment."); } SOAPInvocationData soapInvocationData = (SOAPInvocationData)webServicesInvocationData; //SOAPMessage message = (SOAPMessage)context.getRequestData(); SOAPMessage message = null; SOAPElement securityElement = null; Iterator it = message.getSOAPHeader().getChildElements(WS_SECURITY_ELEMENT); if (it.hasNext()) { securityElement = (SOAPElement)it.next(); } else { securityElement = message.getSOAPHeader().addChildElement(WS_SECURITY_ELEMENT); } if (mustUnderstand) securityElement.addAttribute(new QName(soapInvocationData.getVersion().getNamespace(), "mustUnderstand"), soapInvocationData.getVersion().getMustUnderstandAttribute()); else securityElement.addAttribute(new QName(soapInvocationData.getVersion().getNamespace(), "mustUnderstand"), soapInvocationData.getVersion().getDoNotNeedToUnderstandAttribute()); if (securityElement.getChildElements(WS_TIMESTAMP_ELEMENT).hasNext()) { Node child = (Node)securityElement.getChildElements(WS_TIMESTAMP_ELEMENT).next(); securityElement.removeChild(child); } SOAPElement wsTimestampElement = securityElement.addChildElement(WS_TIMESTAMP_ELEMENT); SOAPElement created = wsTimestampElement.addChildElement(new QName(WS_SECURITY_UTILITY_NAMESPACE, "Created")); Calendar calendar = Calendar.getInstance(); created.setValue(DateTimeUtils.getXMLTimestamp(calendar.getTime())); SOAPElement expires = wsTimestampElement.addChildElement(new QName(WS_SECURITY_UTILITY_NAMESPACE, "Expires")); unit.add(calendar, (int)modifier); expires.setValue(DateTimeUtils.getXMLTimestamp(calendar.getTime())); } catch (SOAPException ex) { throw new InstallFeatureException(ex); } } @Override public String toString() { return "WS-Security timestamp feature"; } }