|
1 | | -// Copyright © 2017, 2019 IBM Corp. All rights reserved. |
| 1 | +// Copyright © 2017, 2021 IBM Corp. All rights reserved. |
2 | 2 | // |
3 | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | 4 | // you may not use this file except in compliance with the License. |
@@ -67,6 +67,9 @@ const MOCK_IAM_SESSION = 'IAMSession=dFNyccpWQd1iZF0zWTCwFDEEFTESPk8X21cygDdoe1R |
67 | 67 | const MOCK_SET_IAM_SESSION_HEADER = { |
68 | 68 | 'set-cookie': `${MOCK_IAM_SESSION}; Version=1; Max-Age=3599; Secure; Path=/; HttpOnly; Secure` |
69 | 69 | }; |
| 70 | +const MOCK_SET_IAM_SESSION_HEADER_SHORT = { |
| 71 | + 'set-cookie': `${MOCK_IAM_SESSION}; Version=1; Max-Age=2; Secure; Path=/; HttpOnly; Secure` |
| 72 | +}; |
70 | 73 |
|
71 | 74 | describe('#db IAMAuth Plugin', function() { |
72 | 75 | beforeEach(function() { |
@@ -315,6 +318,84 @@ describe('#db IAMAuth Plugin', function() { |
315 | 318 | }); |
316 | 319 | }); |
317 | 320 |
|
| 321 | + it('iam_session returns error', function() { |
| 322 | + if (process.env.NOCK_OFF) { |
| 323 | + this.skip(); |
| 324 | + } |
| 325 | + |
| 326 | + var iamMocks = nock(TOKEN_SERVER) |
| 327 | + .post('/identity/token', { |
| 328 | + 'grant_type': 'urn:ibm:params:oauth:grant-type:apikey', |
| 329 | + 'response_type': 'cloud_iam', |
| 330 | + 'apikey': IAM_API_KEY |
| 331 | + }) |
| 332 | + .times(3) |
| 333 | + .reply(200, MOCK_IAM_TOKEN_RESPONSE); |
| 334 | + |
| 335 | + var cloudantMocks = nock(SERVER) |
| 336 | + .post('/_iam_session', {access_token: MOCK_ACCESS_TOKEN}) |
| 337 | + .times(3) |
| 338 | + .replyWithError({code: 'ECONNRESET', message: 'socket hang up'}); |
| 339 | + |
| 340 | + var cloudantClient = new Cloudant({ url: SERVER, plugins: { iamauth: { autoRenew: false, iamApiKey: IAM_API_KEY } } }); |
| 341 | + return assert.rejects( |
| 342 | + cloudantClient.db.get(DBNAME), |
| 343 | + { |
| 344 | + code: 'ECONNRESET', |
| 345 | + description: 'socket hang up' |
| 346 | + }, |
| 347 | + 'Should have rejected with a socket hang up error').finally(() => { |
| 348 | + iamMocks.done(); |
| 349 | + cloudantMocks.done(); |
| 350 | + }); |
| 351 | + }); |
| 352 | + |
| 353 | + it('iam_session returns error on renew', function() { |
| 354 | + if (process.env.NOCK_OFF) { |
| 355 | + this.skip(); |
| 356 | + } |
| 357 | + |
| 358 | + var iamMocks = nock(TOKEN_SERVER) |
| 359 | + .post('/identity/token', { |
| 360 | + 'grant_type': 'urn:ibm:params:oauth:grant-type:apikey', |
| 361 | + 'response_type': 'cloud_iam', |
| 362 | + 'apikey': IAM_API_KEY |
| 363 | + }) |
| 364 | + .times(2) |
| 365 | + .reply(200, MOCK_IAM_TOKEN_RESPONSE); |
| 366 | + |
| 367 | + var cloudantMocks = nock(SERVER) |
| 368 | + .post('/_iam_session', {access_token: MOCK_ACCESS_TOKEN}) |
| 369 | + .reply(200, {ok: true}, MOCK_SET_IAM_SESSION_HEADER_SHORT) |
| 370 | + .get(DBNAME) |
| 371 | + .reply(200, {doc_count: 0}) |
| 372 | + .post('/_iam_session', {access_token: MOCK_ACCESS_TOKEN}) |
| 373 | + .replyWithError({code: 'ECONNRESET', message: 'socket hang up'}) |
| 374 | + .get(DBNAME) |
| 375 | + .reply(401, {error: 'unauthorized', reason: 'Unauthorized'}); |
| 376 | + |
| 377 | + var cloudantClient = new Cloudant({ url: SERVER, maxAttempt: 1, plugins: { iamauth: { iamApiKey: IAM_API_KEY } } }); |
| 378 | + return cloudantClient.db.get(DBNAME.substring(1)) /* Remove leading slash */ |
| 379 | + .then(() => { |
| 380 | + // Wait for long enough for the background renewal to fail and the token to expire |
| 381 | + return new Promise(resolve => setTimeout(resolve, 2100)); |
| 382 | + }) |
| 383 | + .then(() => { |
| 384 | + return assert.rejects( |
| 385 | + cloudantClient.db.get(DBNAME.substring(1)), |
| 386 | + { |
| 387 | + error: 'unauthorized', |
| 388 | + reason: 'Unauthorized', |
| 389 | + statusCode: 401 |
| 390 | + }, |
| 391 | + 'Should have rejected unauthorized after background renewal failure'); |
| 392 | + }) |
| 393 | + .finally(() => { |
| 394 | + iamMocks.done(); |
| 395 | + cloudantMocks.done(); |
| 396 | + }); |
| 397 | + }); |
| 398 | + |
318 | 399 | it('retries access token post on error and returns 200 response', function(done) { |
319 | 400 | if (process.env.NOCK_OFF) { |
320 | 401 | this.skip(); |
|
0 commit comments