Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions src/cmap/auth/mongo_credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,6 @@ export class MongoCredentials {
this.mechanism = options.mechanism || AuthMechanism.MONGODB_DEFAULT;
this.mechanismProperties = options.mechanismProperties || {};

if (this.mechanism.match(/MONGODB-AWS/i)) {
if (!this.username && process.env.AWS_ACCESS_KEY_ID) {
this.username = process.env.AWS_ACCESS_KEY_ID;
}

if (!this.password && process.env.AWS_SECRET_ACCESS_KEY) {
this.password = process.env.AWS_SECRET_ACCESS_KEY;
}

if (
this.mechanismProperties.AWS_SESSION_TOKEN == null &&
process.env.AWS_SESSION_TOKEN != null
) {
this.mechanismProperties = {
...this.mechanismProperties,
AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN
};
}
}

if (this.mechanism === AuthMechanism.MONGODB_OIDC && !this.mechanismProperties.ALLOWED_HOSTS) {
this.mechanismProperties = {
...this.mechanismProperties,
Expand Down
132 changes: 104 additions & 28 deletions test/integration/auth/mongodb_aws.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,39 +163,115 @@ describe('MONGODB-AWS', function () {
});
});

context('when user supplies a credentials provider', function () {
let providerCount = 0;
context('when using a custom credential provider', function () {
context('1. Custom Credential Provider Authenticates', function () {
let providerCount = 0;

beforeEach(function () {
// If we have a username the credentials have been set from the URI, options, or environment
// variables per the auth spec stated order.
if (client.options.credentials.username) {
this.skipReason = 'Credentials in the URI on env variables will not use custom provider.';
return this.skip();
}
beforeEach(function () {
// If we have a username the credentials have been set from the URI, options, or environment
// variables per the auth spec stated order.
if (client.options.credentials.username) {
this.skipReason = 'Credentials in the URI will not use custom provider.';
return this.skip();
}
});

it('authenticates with a user provided credentials provider', async function () {
const credentialProvider = AWSSDKCredentialProvider.awsSDK;
const provider = async () => {
providerCount++;
return await credentialProvider.fromNodeProviderChain().apply();
};
client = this.configuration.newClient(process.env.MONGODB_URI, {
authMechanismProperties: {
AWS_CREDENTIAL_PROVIDER: provider
}
});

const result = await client
.db('aws')
.collection('aws_test')
.estimatedDocumentCount()
.catch(error => error);

expect(result).to.not.be.instanceOf(MongoServerError);
expect(result).to.be.a('number');
expect(providerCount).to.be.greaterThan(0);
});
});

it('authenticates with a user provided credentials provider', async function () {
const credentialProvider = AWSSDKCredentialProvider.awsSDK;
const provider = async () => {
providerCount++;
return await credentialProvider.fromNodeProviderChain().apply();
};
client = this.configuration.newClient(process.env.MONGODB_URI, {
authMechanismProperties: {
AWS_CREDENTIAL_PROVIDER: provider
}
context('2. Custom Credential Provider Authentication Precedence', function () {
context('Case 1: Credentials in URI Take Precedence', function () {
let providerCount = 0;
let provider;

beforeEach(function () {
console.log(client?.options);
if (!client?.options.credentials.username) {
this.skipReason = 'Test only runs when credentials are present in the URI';
return this.skip();
}
const credentialProvider = AWSSDKCredentialProvider.awsSDK;
provider = async () => {
providerCount++;
return await credentialProvider.fromNodeProviderChain().apply();
};
});

it('authenticates with a user provided credentials provider', async function () {
console.log(process.env);
client = this.configuration.newClient(process.env.MONGODB_URI, {
authMechanismProperties: {
AWS_CREDENTIAL_PROVIDER: provider
}
});

const result = await client
.db('aws')
.collection('aws_test')
.estimatedDocumentCount()
.catch(error => error);

expect(result).to.not.be.instanceOf(MongoServerError);
expect(result).to.be.a('number');
expect(providerCount).to.equal(0);
});
});

const result = await client
.db('aws')
.collection('aws_test')
.estimatedDocumentCount()
.catch(error => error);
context('Case 2: Custom Provider Takes Precedence Over Environment Variables', function () {
let providerCount = 0;
let provider;

expect(result).to.not.be.instanceOf(MongoServerError);
expect(result).to.be.a('number');
expect(providerCount).to.be.greaterThan(0);
beforeEach(function () {
if (client?.options.credentials.username || !process.env.AWS_ACCESS_KEY_ID) {
this.skipReason = 'Test only runs when credentials are present in the environment';
return this.skip();
}
const credentialProvider = AWSSDKCredentialProvider.awsSDK;
provider = async () => {
providerCount++;
return await credentialProvider.fromNodeProviderChain().apply();
};
});

it('authenticates with a user provided credentials provider', async function () {
client = this.configuration.newClient(process.env.MONGODB_URI, {
authMechanismProperties: {
AWS_CREDENTIAL_PROVIDER: provider
}
});

const result = await client
.db('aws')
.collection('aws_test')
.estimatedDocumentCount()
.catch(error => error);

expect(result).to.not.be.instanceOf(MongoServerError);
expect(result).to.be.a('number');
expect(providerCount).to.be.greaterThan(0);
});
});
});
});

Expand All @@ -218,7 +294,7 @@ describe('MONGODB-AWS', function () {
.catch(error => error);

expect(client).to.have.nested.property('s.authProviders');
const provider = client.s.authProviders.getOrCreateProvider('MONGODB-AWS');
const provider = client.s.authProviders.getOrCreateProvider('MONGODB-AWS', {});
expect(provider).to.be.instanceOf(MongoDBAWS);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,49 @@ describe('26. Custom AWS Credential Providers', metadata, () => {
});
}
);

context(
'ClientEncryption with credentialProviders and valid environment variables',
metadata,
function () {
let clientEncryption;
let providerCount = 0;
let previousAccessKey;
let previousSecretKey;

beforeEach(function () {
previousAccessKey = process.env.AWS_ACCESS_KEY_ID;
previousSecretKey = process.env.AWS_SECRET_ACCESS_KEY;
process.env.AWS_ACCESS_KEY_ID = process.env.FLE_AWS_KEY;
process.env.AWS_SECRET_ACCESS_KEY = process.env.FLE_AWS_SECRET;

const options = {
keyVaultNamespace: 'keyvault.datakeys',
kmsProviders: { aws: {} },
credentialProviders: {
aws: async () => {
providerCount++;
return {
accessKeyId: process.env.FLE_AWS_KEY,
secretAccessKey: process.env.FLE_AWS_SECRET
};
}
},
extraOptions: getEncryptExtraOptions()
};
clientEncryption = new ClientEncryption(keyVaultClient, options);
});

afterEach(function () {
process.env.AWS_ACCESS_KEY_ID = previousAccessKey;
process.env.AWS_SECRET_ACCESS_KEY = previousSecretKey;
});

it('is successful', metadata, async function () {
const dk = await clientEncryption.createDataKey('aws', { masterKey });
expect(dk).to.be.instanceOf(Binary);
expect(providerCount).to.be.greaterThan(0);
});
}
);
});