Skip to content

Commit 979be44

Browse files
authored
Merge pull request #15 from ssbrewster/DF-85
2 parents 087ecb7 + 3d83c42 commit 979be44

File tree

6 files changed

+181
-60
lines changed

6 files changed

+181
-60
lines changed

lib/auth.js

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,37 @@ authenticator.getAccessToken = function(tenantId, spnAppPrincipalId, spnSymmetri
1818
var key = new Buffer(spnSymmetricKeyBase64, 'base64');
1919
var token = jwt.encode(payload, key);
2020
var data = {
21-
grant_type: 'http://oauth.net/grant_type/jwt/1.0/bearer',
22-
assertion: token,
23-
resource: '00000002-0000-0000-c000-000000000000/directory.windows.net@' + tenantId
24-
};
21+
grant_type: 'http://oauth.net/grant_type/jwt/1.0/bearer',
22+
assertion: token,
23+
resource: '00000002-0000-0000-c000-000000000000/directory.windows.net@' + tenantId
24+
};
2525

2626
request.post('https://accounts.accesscontrol.windows.net/tokens/OAuth/2', { form: data }, function(e, resp, body) {
2727
if (e) return callback(e, null);
2828

29+
var parsedBody;
30+
31+
try {
32+
parsedBody = JSON.parse(body);
33+
} catch (e) {
34+
var message = e.message || 'Failed to parse response from graph API';
35+
var parseError = new Error(message);
36+
37+
parseError.name = e.name || 'waad_parse_error';
38+
parseError.stack = e.stack;
39+
parseError.body = body;
40+
return callback(parseError);
41+
}
42+
2943
if (resp.statusCode != 200) {
30-
try {
31-
var response = JSON.parse(body);
32-
if (response.error) {
33-
return callback(new OAuthError(response.error_description || response.error, response), null);
34-
}
44+
if (parsedBody.error) {
45+
return callback(new OAuthError(parsedBody.error_description || parsedBody.error, parsedBody), null);
3546
}
36-
catch(err) {}
3747

3848
return callback(new OAuthError(body), null);
3949
}
4050

41-
callback(null, JSON.parse(body).access_token);
51+
callback(null, parsedBody.access_token);
4252
});
4353
};
4454

@@ -51,28 +61,38 @@ authenticator.getGraphClient = function (tenantId, spnAppPrincipalId, spnSymmetr
5161

5262
authenticator.getAccessTokenWithClientCredentials = function(tenantDomain, appDomain, clientId, clientSecret, callback) {
5363
var data = {
54-
grant_type: 'client_credentials',
55-
client_id: clientId + '/' + appDomain + '@' + tenantDomain,
56-
client_secret: clientSecret,
57-
resource: '00000002-0000-0000-c000-000000000000/graph.windows.net@' + tenantDomain
58-
};
64+
grant_type: 'client_credentials',
65+
client_id: clientId + '/' + appDomain + '@' + tenantDomain,
66+
client_secret: clientSecret,
67+
resource: '00000002-0000-0000-c000-000000000000/graph.windows.net@' + tenantDomain
68+
};
5969

6070
request.post('https://accounts.accesscontrol.windows.net/' + tenantDomain + '/tokens/OAuth/2', { form: data }, function(e, resp, body) {
6171
if (e) return callback(e, null);
6272

73+
var parsedBody;
74+
75+
try {
76+
parsedBody = JSON.parse(body);
77+
} catch(e){
78+
var message = e.message || 'Failed to parse response from graph API';
79+
var parseError = new Error(message);
80+
81+
parseError.name = e.name || 'waad_parse_error';
82+
parseError.stack = e.stack;
83+
parseError.body = body;
84+
return callback(parseError);
85+
}
86+
6387
if (resp.statusCode != 200) {
64-
try {
65-
var response = JSON.parse(body);
66-
if (response.error) {
67-
return callback(new OAuthError(response.error_description || response.error, response), null);
68-
}
88+
if (parsedBody.error) {
89+
return callback(new OAuthError(parsedBody.error_description || parsedBody.error, parsedBody), null);
6990
}
70-
catch (exp) {}
7191

7292
return callback(new OAuthError(body), null);
7393
}
7494

75-
callback(null, JSON.parse(body).access_token);
95+
callback(null, parsedBody.access_token);
7696
});
7797
};
7898

@@ -87,19 +107,29 @@ authenticator.getAccessTokenWithClientCredentials2 = function(tenantDomain, clie
87107
request.post('https://login.windows.net/' + tenantDomain + '/oauth2/token', { form: data }, function(e, resp, body) {
88108
if (e) return callback(e, null);
89109

110+
var parsedBody;
111+
112+
try {
113+
parsedBody = JSON.parse(body);
114+
} catch(e){
115+
var message = e.message || 'Failed to parse response from graph API';
116+
var parseError = new Error(message);
117+
118+
parseError.name = e.name || 'waad_parse_error';
119+
parseError.stack = e.stack;
120+
parseError.body = body;
121+
return callback(parseError);
122+
}
123+
90124
if (resp.statusCode != 200) {
91-
try {
92-
var response = JSON.parse(body);
93-
if (response.error) {
94-
return callback(new OAuthError(response.error_description || response.error, response), null);
95-
}
125+
if (parsedBody.error) {
126+
return callback(new OAuthError(parsedBody.error_description || parsedBody.error, parsedBody), null);
96127
}
97-
catch (exp) {}
98128

99129
return callback(new OAuthError(body), null);
100130
}
101131

102-
callback(null, JSON.parse(body).access_token);
132+
callback(null, parsedBody.access_token);
103133
});
104134
};
105135

@@ -124,4 +154,3 @@ authenticator.getGraphClient10 = function(tenantDomain, clientId, clientSecret,
124154
});
125155
};
126156

127-

lib/waad.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@ Waad.prototype.__queryUserGroup = function (user, headers, callback) {
3939
try {
4040
parsedBody = JSON.parse(body);
4141
} catch(e){
42-
return callback(new Error('Failed to parse response from graph API'));
42+
var message = e.message || 'Failed to parse response from graph API';
43+
var parseError = new Error(message);
44+
45+
parseError.name = e.name || 'waad_parse_error';
46+
parseError.stack = e.stack;
47+
parseError.body = body;
48+
return callback(parseError);
4349
}
4450

4551
var groups = parsedBody.d.results;
@@ -74,7 +80,13 @@ Waad.prototype.__queryUsers = function (qs, options, callback) {
7480
try {
7581
parsedBody = JSON.parse(body);
7682
} catch (e){
77-
return callback(new Error('Failed to parse response from graph API'));
83+
var message = e.message || 'Failed to parse response from graph API';
84+
var parseError = new Error(message);
85+
86+
parseError.name = e.name || 'waad_parse_error';
87+
parseError.stack = e.stack;
88+
parseError.body = body;
89+
return callback(parseError);
7890
}
7991

8092
var d = parsedBody.d,

lib/waad10.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ Waad10.prototype.__request = function (options, callback) {
4949
try {
5050
array = JSON.parse(body);
5151
} catch (e){
52-
return callback(new Error('Failed to parse response from graph API'));
52+
var message = e.message || 'Failed to parse response from graph API';
53+
var parseError = new Error(message);
54+
55+
parseError.name = e.name || 'waad_parse_error';
56+
parseError.stack = e.stack;
57+
parseError.body = body;
58+
return callback(parseError);
5359
}
5460
}
5561

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-waad",
3-
"version": "2.4.0",
3+
"version": "2.4.1",
44
"description": "query windows azure active directory",
55
"main": "./lib",
66
"scripts": {
@@ -11,6 +11,7 @@
1111
"lodash": "~1.0.0-rc.3",
1212
"mocha": "*",
1313
"nconf": "^0.10.0",
14+
"nock": "^10.0.1",
1415
"should": "~1.2.1"
1516
},
1617
"keywords": [

test/auth.tests.js

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
11
var assert = require('assert')
2-
, auth = require("../lib/auth")
3-
, config = require('./config');
2+
, auth = require("../lib/auth")
3+
, config = require('./config');
44

55
describe('login to waad', function () {
6-
it('should obtain an access token', function (done) {
7-
auth.getAccessToken(config.v1.TENANTID, config.v1.APPPRINCIPALID, config.v1.SYMMETRICKEY, function(err, token) {
8-
if (err) {
9-
console.log(err);
10-
}
6+
it('should obtain an access token', function (done) {
7+
auth.getAccessToken(config.v1.TENANTID, config.v1.APPPRINCIPALID, config.v1.SYMMETRICKEY, function(err, token) {
8+
if (err) {
9+
console.log(err);
10+
return done(err);
11+
}
1112

12-
assert.notEqual(null, token);
13-
done();
14-
});
13+
assert.notEqual(null, token);
14+
done();
1515
});
16+
});
1617

17-
it('should fail for wrong tenantId', function (done) {
18-
auth.getAccessToken('wrong-tenant-id', config.v1.APPPRINCIPALID, config.v1.SYMMETRICKEY, function(err, token) {
19-
assert.ok(err.message.indexOf('AADSTS90002: No service namespace named \'wrong-tenant-id\' was found in the data store.'));
20-
done();
21-
});
18+
it('should fail for wrong tenantId', function (done) {
19+
auth.getAccessToken('wrong-tenant-id', config.v1.APPPRINCIPALID, config.v1.SYMMETRICKEY, function(err, token) {
20+
assert.ok(err.message.indexOf('AADSTS90002: No service namespace named \'wrong-tenant-id\' was found in the data store.'));
21+
done();
2222
});
23+
});
2324

24-
it('should fail for wrong service principal', function (done) {
25-
auth.getAccessToken(config.v1.TENANTID, 'wrong-principal', config.v1.SYMMETRICKEY, function(err, token) {
26-
assert.ok(err.message.indexOf('AADSTS70001: Application with identifier \'wrong-principal\' was not found in the directory') > -1);
27-
done();
28-
});
25+
it('should fail for wrong service principal', function (done) {
26+
auth.getAccessToken(config.v1.TENANTID, 'wrong-principal', config.v1.SYMMETRICKEY, function(err, token) {
27+
assert.ok(err.message.indexOf('AADSTS70001: Application with identifier \'wrong-principal\' was not found in the directory') > -1);
28+
done();
2929
});
30+
});
3031

31-
it('should fail for wrong service key', function (done) {
32-
auth.getAccessToken(config.v1.TENANTID, config.v1.APPPRINCIPALID, 'wrong-key', function(err, token) {
33-
assert.ok(err.message.indexOf('AADSTS70002: Error validating credentials. AADSTS50012: Client assertion contains an invalid signature.') > -1);
34-
done();
35-
});
32+
it('should fail for wrong service key', function (done) {
33+
auth.getAccessToken(config.v1.TENANTID, config.v1.APPPRINCIPALID, 'wrong-key', function(err, token) {
34+
assert.ok(err.message.indexOf('AADSTS70002: Error validating credentials. AADSTS50012: Client assertion contains an invalid signature.') > -1);
35+
done();
3636
});
37+
});
3738
});

test/auth2.tests.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
var assert = require('assert')
2+
, auth = require('../lib/auth')
3+
, config = require('./config')
4+
, nock = require('nock');
5+
6+
describe('login to waad', function () {
7+
function assertParseError(actual, expected, token) {
8+
assert.deepEqual(actual, expected);
9+
assert.equal(token, null);
10+
}
11+
12+
var message = 'Failed to parse response from graph API';
13+
var parseError = new Error(message);
14+
15+
parseError.name = 'waad_parse_error';
16+
parseError.stack = 'Error stack'
17+
parseError.body = { error: 'body' };
18+
19+
var tenantId = config.v1.TENANTID;
20+
var spnAppPrincipalId = config.v1.APPPRINCIPALID;
21+
var spnSymmetricKeyBase64 = config.v1.SYMMETRICKEY;
22+
var tenantDomain = config.v2.WAAD_TENANTDOMAIN;
23+
var clientId = config.v2.WAAD_CLIENTID;
24+
var clientSecret = config.v2.WAAD_CLIENTSECRET;
25+
26+
describe('v1 fails to parse JSON response', function () {
27+
afterEach(function () {
28+
nock.cleanAll();
29+
});
30+
31+
it('should return error details when it fails to parse the JSON response when getting an access token', function (done) {
32+
nock('https://accounts.accesscontrol.windows.net')
33+
.post('/tokens/OAuth/2')
34+
.replyWithError(parseError);
35+
36+
auth.getAccessToken(tenantId, spnAppPrincipalId, spnSymmetricKeyBase64, function(err, token) {
37+
assertParseError(err, parseError, token);
38+
done();
39+
});
40+
});
41+
42+
it('should return error details when it fails to parse the JSON response when getting an access token with client credentials', function (done) {
43+
nock('https://accounts.accesscontrol.windows.net')
44+
.post('/' + tenantId + '/tokens/OAuth/2')
45+
.replyWithError(parseError);
46+
47+
auth.getAccessTokenWithClientCredentials(tenantId, spnAppPrincipalId, clientId, clientSecret, function(err, token) {
48+
assertParseError(err, parseError, token);
49+
done();
50+
});
51+
});
52+
});
53+
54+
describe('v2 fails to parse JSON response', function () {
55+
beforeEach(function () {
56+
nock('https://login.windows.net')
57+
.post('/' + tenantDomain + '/oauth2/token')
58+
.replyWithError(parseError);
59+
});
60+
61+
afterEach(function () {
62+
nock.cleanAll();
63+
});
64+
65+
it('should return error details when it fails to parse the JSON response', function (done) {
66+
auth.getAccessTokenWithClientCredentials2(tenantDomain, clientId, clientSecret, function(err, token) {
67+
assertParseError(err, parseError, token);
68+
done();
69+
});
70+
});
71+
});
72+
});

0 commit comments

Comments
 (0)