From cbaf47a08dd478a8e469bd96e95a33fc8306802e Mon Sep 17 00:00:00 2001 From: Alena Khineika Date: Tue, 5 Mar 2024 15:44:17 +0100 Subject: [PATCH] fix(NODE-5945): make AWS session token optional (#4006) Co-authored-by: Neal Beeken --- src/cmap/auth/mongodb_aws.ts | 6 +++- test/integration/auth/mongodb_aws.test.ts | 39 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/cmap/auth/mongodb_aws.ts b/src/cmap/auth/mongodb_aws.ts index 0e430dd1ac..78dcceb02c 100644 --- a/src/cmap/auth/mongodb_aws.ts +++ b/src/cmap/auth/mongodb_aws.ts @@ -116,6 +116,7 @@ export class MongoDBAWS extends AuthProvider { const accessKeyId = credentials.username; const secretAccessKey = credentials.password; + // Allow the user to specify an AWS session token for authentication with temporary credentials. const sessionToken = credentials.mechanismProperties.AWS_SESSION_TOKEN; // If all three defined, include sessionToken, else include username and pass, else no credentials @@ -129,6 +130,8 @@ export class MongoDBAWS extends AuthProvider { const db = credentials.source; const nonce = await randomBytes(32); + // All messages between MongoDB clients and servers are sent as BSON objects + // in the payload field of saslStart and saslContinue. const saslStart = { saslStart: 1, mechanism: 'MONGODB-AWS', @@ -212,7 +215,8 @@ async function makeTempCredentials( provider?: () => Promise ): Promise { function makeMongoCredentialsFromAWSTemp(creds: AWSTempCredentials) { - if (!creds.AccessKeyId || !creds.SecretAccessKey || !creds.Token) { + // The AWS session token (creds.Token) may or may not be set. + if (!creds.AccessKeyId || !creds.SecretAccessKey) { throw new MongoMissingCredentialsError('Could not obtain temporary MONGODB-AWS credentials'); } diff --git a/test/integration/auth/mongodb_aws.test.ts b/test/integration/auth/mongodb_aws.test.ts index 1981324939..49abc9afde 100644 --- a/test/integration/auth/mongodb_aws.test.ts +++ b/test/integration/auth/mongodb_aws.test.ts @@ -5,7 +5,13 @@ import * as http from 'http'; import { performance } from 'perf_hooks'; import * as sinon from 'sinon'; -import { MongoAWSError, type MongoClient, MongoDBAWS, MongoServerError } from '../../mongodb'; +import { + MongoAWSError, + type MongoClient, + MongoDBAWS, + MongoMissingCredentialsError, + MongoServerError +} from '../../mongodb'; function awsSdk() { try { @@ -81,6 +87,37 @@ describe('MONGODB-AWS', function () { expect(provider).to.be.instanceOf(MongoDBAWS); }); + describe('with missing aws token', () => { + let awsSessionToken: string | undefined; + + beforeEach(() => { + awsSessionToken = process.env.AWS_SESSION_TOKEN; + delete process.env.AWS_SESSION_TOKEN; + }); + + afterEach(() => { + if (awsSessionToken != null) { + process.env.AWS_SESSION_TOKEN = awsSessionToken; + } + }); + + it('should not throw an exception when aws token is missing', async function () { + client = this.configuration.newClient(process.env.MONGODB_URI); + + const result = await client + .db('aws') + .collection('aws_test') + .estimatedDocumentCount() + .catch(error => error); + + // We check only for the MongoMissingCredentialsError + // and do check for the MongoServerError as the error or numeric result + // that can be returned depending on different types of environments + // getting credentials from different sources. + expect(result).to.not.be.instanceOf(MongoMissingCredentialsError); + }); + }); + describe('EC2 with missing credentials', () => { let client;