Skip to content

Commit

Permalink
Merge pull request #579 from roiemir/master
Browse files Browse the repository at this point in the history
Respond with security timestamp if request had one
  • Loading branch information
herom committed Feb 27, 2015
2 parents 80cccc2 + 5b570b7 commit 9b147db
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
47 changes: 38 additions & 9 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ function findKey(obj, val) {
return n;
}

function getDateString(d) {
function pad(n) {
return n < 10 ? '0' + n : n;
}
return d.getUTCFullYear() + '-'
+ pad(d.getUTCMonth() + 1) + '-'
+ pad(d.getUTCDate()) + 'T'
+ pad(d.getUTCHours()) + ':'
+ pad(d.getUTCMinutes()) + ':'
+ pad(d.getUTCSeconds()) + 'Z';
}

var url = require('url'),
compress = null,
events = require('events'),
Expand Down Expand Up @@ -139,7 +151,8 @@ Server.prototype._process = function(input, URL, callback) {
headers = obj.Header,
bindings = this.wsdl.definitions.bindings, binding,
method, methodName,
serviceName, portName;
serviceName, portName,
includeTimestamp = obj.Header && obj.Header.Security && obj.Header.Security.Timestamp;

if (typeof self.authenticate === 'function') {
if (!obj.Header || !obj.Header.Security) {
Expand Down Expand Up @@ -219,22 +232,22 @@ Server.prototype._process = function(input, URL, callback) {
args: body[messageElemName],
headers: headers,
style: 'document'
}, callback);
}, callback, includeTimestamp);
}
}
catch (e) {
if (e.Fault !== undefined) {
// 3rd param is the NS prepended to all elements
// It must match the NS defined in the Envelope (set by the _envelope method)
var fault = self.wsdl.objectToDocumentXML("Fault", e.Fault, "soap");
callback(self._envelope(fault));
callback(self._envelope(fault, includeTimestamp));
}
else
throw e;
}
};

Server.prototype._executeMethod = function(options, callback) {
Server.prototype._executeMethod = function(options, callback, includeTimestamp) {
options = options || {};
var self = this,
method, body,
Expand All @@ -249,7 +262,7 @@ Server.prototype._executeMethod = function(options, callback) {
try {
method = this.services[serviceName][portName][methodName];
} catch (e) {
return callback(this._envelope(''));
return callback(this._envelope('', includeTimestamp));
}

function handleResult(result) {
Expand All @@ -263,7 +276,7 @@ Server.prototype._executeMethod = function(options, callback) {
var element = self.wsdl.definitions.services[serviceName].ports[portName].binding.methods[methodName].output;
body = self.wsdl.objectToDocumentXML(outputName, result, element.targetNSAlias, element.targetNamespace);
}
callback(self._envelope(body));
callback(self._envelope(body, includeTimestamp));
}

var result = method(args, handleResult, options.headers);
Expand All @@ -272,16 +285,32 @@ Server.prototype._executeMethod = function(options, callback) {
}
};

Server.prototype._envelope = function(body) {
Server.prototype._envelope = function(body, includeTimestamp) {
var defs = this.wsdl.definitions,
ns = defs.$targetNamespace,
encoding = '',
alias = findKey(defs.xmlns, ns);
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
encoding +
this.wsdl.xmlnsInEnvelope + '>' +
"<soap:Body>" +
this.wsdl.xmlnsInEnvelope + '>';
if (includeTimestamp) {
var now = new Date();
var created = getDateString(now);
var expires = getDateString(new Date(now.getTime() + (1000 * 600)));

xml += "<soap:Header>" +
" <o:Security soap:mustUnderstand=\"1\" " +
"xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" " +
"xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
" <u:Timestamp u:Id=\"_0\">" +
" <u:Created>" + created + "</u:Created>" +
" <u:Expires>" + expires + "</u:Expires>" +
" </u:Timestamp>" +
" </o:Security>" +
"</soap:Header>";
}
xml += "<soap:Body>" +
body +
"</soap:Body>" +
"</soap:Envelope>";
Expand Down
12 changes: 12 additions & 0 deletions test/server-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ describe('SOAP Server', function() {
});
});

it('should return security timestamp in response', function(done) {
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
assert.ok(!err);
client.addSoapHeader('<Security><Timestamp><Created>2015-02-23T12:00:00.000Z</Created><Expires>2015-02-23T12:05:00.000Z</Expires></Timestamp></Security>');
client.GetLastTradePrice({ tickerSymbol: 'AAPL'}, function(err, result, raw, soapHeader) {
assert.ok(!err);
assert.ok(soapHeader && soapHeader.Security && soapHeader.Security.Timestamp);
done();
});
});
});

it('should emit \'headers\' event', function(done) {
test.soapServer.on('headers', function headersManager(headers, methodName) {
assert.equal(methodName, 'GetLastTradePrice');
Expand Down

0 comments on commit 9b147db

Please sign in to comment.