Skip to content

Commit d7f54fa

Browse files
committed
test: update configs
1 parent 33980e7 commit d7f54fa

File tree

7 files changed

+202
-4
lines changed

7 files changed

+202
-4
lines changed

.evergreen/config.in.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,20 @@ tasks:
12091209
args:
12101210
- src/.evergreen/run-azure-kms-tests.sh
12111211

1212+
- name: "oidc-auth-test-azure-latest"
1213+
commands:
1214+
- command: shell.exec
1215+
params:
1216+
shell: bash
1217+
script: |-
1218+
set -o errexit
1219+
${PREPARE_SHELL}
1220+
cd src
1221+
export AZUREOIDC_DRIVERS_TAR_FILE=/tmp/node-mongodb-native.tgz
1222+
tar czf $AZUREOIDC_DRIVERS_TAR_FILE .
1223+
export AZUREOIDC_TEST_CMD="source ./env.sh && PROVIDER_NAME=azure ./.evergreen/run-oidc-tests.sh"
1224+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/azure/run-driver-test.sh
1225+
12121226
12131227
task_groups:
12141228
- name: serverless_task_group
@@ -1313,6 +1327,37 @@ task_groups:
13131327
tasks:
13141328
- test-azurekms-task
13151329

1330+
- name: testazureoidc_task_group
1331+
setup_group:
1332+
- func: fetch source
1333+
# - func: prepare resources
1334+
# - func: fix absolute paths
1335+
# - func: make files executable
1336+
- command: shell.exec
1337+
params:
1338+
shell: bash
1339+
script: |-
1340+
set -o errexit
1341+
${PREPARE_SHELL}
1342+
export AZUREOIDC_CLIENTID="${testazureoidc_clientid}"
1343+
export AZUREOIDC_TENANTID="${testazureoic_tenantid}"
1344+
export AZUREOIDC_SECRET="${testazureoidc_secret}"
1345+
export AZUREOIDC_KEYVAULT=${testazureoidc_keyvault}
1346+
export AZUREOIDC_DRIVERS_TOOLS="$DRIVERS_TOOLS"
1347+
export AZUREOIDC_VMNAME_PREFIX="NODE_DRIVER"
1348+
$DRIVERS_TOOLS/.evergreen/auth_oidc/azure/create-and-setup-vm.sh
1349+
teardown_group:
1350+
- command: shell.exec
1351+
params:
1352+
shell: bash
1353+
script: |-
1354+
${PREPARE_SHELL}
1355+
$DRIVERS_TOOLS/.evergreen/auth_oidc/azure/delete-vm.sh
1356+
setup_group_can_fail_task: true
1357+
setup_group_timeout_secs: 1800
1358+
tasks:
1359+
- oidc-auth-test-azure-latest
1360+
13161361
pre:
13171362
- func: "fetch source"
13181363
- func: "windows fix"

.evergreen/config.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,19 @@ tasks:
11361136
EXPECTED_AZUREKMS_OUTCOME: failure
11371137
args:
11381138
- src/.evergreen/run-azure-kms-tests.sh
1139+
- name: oidc-auth-test-azure-latest
1140+
commands:
1141+
- command: shell.exec
1142+
params:
1143+
shell: bash
1144+
script: |-
1145+
set -o errexit
1146+
${PREPARE_SHELL}
1147+
cd src
1148+
export AZUREOIDC_DRIVERS_TAR_FILE=/tmp/node-mongodb-native.tgz
1149+
tar czf $AZUREOIDC_DRIVERS_TAR_FILE .
1150+
export AZUREOIDC_TEST_CMD="source ./env.sh && PROVIDER_NAME=azure ./.evergreen/run-oidc-tests.sh"
1151+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/azure/run-driver-test.sh
11391152
- name: test-latest-server
11401153
tags:
11411154
- latest
@@ -3191,6 +3204,33 @@ task_groups:
31913204
- ${DRIVERS_TOOLS}/.evergreen/csfle/azurekms/delete-vm.sh
31923205
tasks:
31933206
- test-azurekms-task
3207+
- name: testazureoidc_task_group
3208+
setup_group:
3209+
- func: fetch source
3210+
- command: shell.exec
3211+
params:
3212+
shell: bash
3213+
script: |-
3214+
set -o errexit
3215+
${PREPARE_SHELL}
3216+
export AZUREOIDC_CLIENTID="${testazureoidc_clientid}"
3217+
export AZUREOIDC_TENANTID="${testazureoic_tenantid}"
3218+
export AZUREOIDC_SECRET="${testazureoidc_secret}"
3219+
export AZUREOIDC_KEYVAULT=${testazureoidc_keyvault}
3220+
export AZUREOIDC_DRIVERS_TOOLS="$DRIVERS_TOOLS"
3221+
export AZUREOIDC_VMNAME_PREFIX="NODE_DRIVER"
3222+
$DRIVERS_TOOLS/.evergreen/auth_oidc/azure/create-and-setup-vm.sh
3223+
teardown_group:
3224+
- command: shell.exec
3225+
params:
3226+
shell: bash
3227+
script: |-
3228+
${PREPARE_SHELL}
3229+
$DRIVERS_TOOLS/.evergreen/auth_oidc/azure/delete-vm.sh
3230+
setup_group_can_fail_task: true
3231+
setup_group_timeout_secs: 1800
3232+
tasks:
3233+
- oidc-auth-test-azure-latest
31943234
pre:
31953235
- func: fetch source
31963236
- func: windows fix
@@ -3756,6 +3796,12 @@ buildvariants:
37563796
tasks:
37573797
- test_azurekms_task_group
37583798
- test-azurekms-fail-task
3799+
- name: ubuntu20-test-azure-oidc
3800+
display_name: Azure OIDC
3801+
run_on: ubuntu2004-small
3802+
batchtime: 20160
3803+
tasks:
3804+
- testazureoidc_task_group
37593805
- name: rhel8-no-auth-tests
37603806
display_name: No Auth Tests
37613807
run_on: rhel80-large

.evergreen/generate_evergreen_tasks.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,14 @@ BUILD_VARIANTS.push({
681681
tasks: ['test_azurekms_task_group', 'test-azurekms-fail-task']
682682
});
683683

684+
BUILD_VARIANTS.push({
685+
name: 'ubuntu20-test-azure-oidc',
686+
display_name: 'Azure OIDC',
687+
run_on: 'ubuntu2004-small',
688+
batchtime: 20160,
689+
tasks: ['testazureoidc_task_group']
690+
});
691+
684692
BUILD_VARIANTS.push({
685693
name: 'rhel8-no-auth-tests',
686694
display_name: 'No Auth Tests',

src/cmap/auth/mongodb_oidc/azure_service_workflow.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MongoAWSError } from '../../../error';
1+
import { MongoAWSError, MongoMissingCredentialsError } from '../../../error';
22
import { request } from '../../../utils';
33
import { AzureTokenCache } from './azure_token_cache';
44
import { ServiceWorkflow } from './service_workflow';
@@ -13,6 +13,13 @@ const AZURE_BASE_URL =
1313
/** Azure request headers. */
1414
const AZURE_HEADERS = Object.freeze({ Metadata: 'true', Accept: 'application/json' });
1515

16+
/** Properties allowed on results of the endpoint. */
17+
const RESULT_PROPERTIES = ['access_token', 'expires_in'];
18+
19+
/** Invalid endpoint result error. */
20+
const ENDPOINT_RESULT_ERROR =
21+
'Azure endpoint did not return a value with only access_token and expires_in properties';
22+
1623
/**
1724
* The Azure access token format.
1825
* @internal
@@ -46,7 +53,6 @@ export class AzureServiceWorkflow extends ServiceWorkflow {
4653
if (!tokenAudience) {
4754
throw new MongoAWSError(TOKEN_AUDIENCE_MISSING_ERROR);
4855
}
49-
// TODO: Look for the token in the cache. They expire after 5 minutes.
5056
let token;
5157
const entry = this.cache.getEntry(tokenAudience);
5258
if (entry?.isValid()) {
@@ -58,7 +64,10 @@ export class AzureServiceWorkflow extends ServiceWorkflow {
5864
token = azureEntry.token;
5965
}
6066

61-
// TODO: Validate access_token and expires_in are present.
67+
if (isEndpointResultInvalid(token)) {
68+
this.cache.deleteEntry(tokenAudience);
69+
throw new MongoMissingCredentialsError(ENDPOINT_RESULT_ERROR);
70+
}
6271
return token;
6372
}
6473
}
@@ -74,3 +83,14 @@ async function getAzureTokenData(tokenAudience: string): Promise<AzureAccessToke
7483
});
7584
return data as AzureAccessToken;
7685
}
86+
87+
/**
88+
* Determines if a result returned from the endpoint is invalid.
89+
* This means the result is nullish, doesn't contain the access_token required field,
90+
* the expires_in required field, and does not contain extra fields.
91+
*/
92+
function isEndpointResultInvalid(token: unknown): boolean {
93+
if (token == null || typeof token !== 'object') return true;
94+
if (!('access_token' in token) || !('expires_in' in token)) return true;
95+
return !Object.getOwnPropertyNames(token).every(prop => RESULT_PROPERTIES.includes(prop));
96+
}

src/cmap/auth/mongodb_oidc/azure_token_cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class AzureTokenCache extends AbstractCache<AzureTokenEntry> {
2929
}
3030

3131
/**
32-
* Create a cache key from the address and username.
32+
* Create a cache key.
3333
*/
3434
cacheKey(tokenAudience: string): string {
3535
return tokenAudience;

test/mongodb.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ export * from '../src/cmap/auth/mongocr';
107107
export * from '../src/cmap/auth/mongodb_aws';
108108
export * from '../src/cmap/auth/mongodb_oidc';
109109
export * from '../src/cmap/auth/mongodb_oidc/aws_service_workflow';
110+
export * from '../src/cmap/auth/mongodb_oidc/azure_service_workflow';
111+
export * from '../src/cmap/auth/mongodb_oidc/azure_token_cache';
110112
export * from '../src/cmap/auth/mongodb_oidc/callback_lock_cache';
111113
export * from '../src/cmap/auth/mongodb_oidc/callback_workflow';
112114
export * from '../src/cmap/auth/mongodb_oidc/service_workflow';
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { expect } from 'chai';
2+
3+
import { AzureTokenCache } from '../../../../mongodb';
4+
5+
describe('AzureTokenCache', function () {
6+
const tokenResultWithExpiration = Object.freeze({
7+
access_token: 'test',
8+
expires_in: 100
9+
});
10+
11+
describe('#addEntry', function () {
12+
context('when expiresInSeconds is provided', function () {
13+
const cache = new AzureTokenCache();
14+
let entry;
15+
16+
before(function () {
17+
cache.addEntry('audience', tokenResultWithExpiration);
18+
entry = cache.getEntry('audience');
19+
});
20+
21+
it('adds the token result', function () {
22+
expect(entry.tokenResult).to.deep.equal(tokenResultWithExpiration);
23+
});
24+
25+
it('creates an expiration', function () {
26+
expect(entry.expiration).to.be.within(Date.now(), Date.now() + 100 * 1000);
27+
});
28+
});
29+
});
30+
31+
describe('#clear', function () {
32+
const cache = new AzureTokenCache();
33+
34+
before(function () {
35+
cache.addEntry('audience', tokenResultWithExpiration);
36+
cache.clear();
37+
});
38+
39+
it('clears the cache', function () {
40+
expect(cache.entries.size).to.equal(0);
41+
});
42+
});
43+
44+
describe('#deleteEntry', function () {
45+
const cache = new AzureTokenCache();
46+
47+
before(function () {
48+
cache.addEntry('audience', tokenResultWithExpiration);
49+
cache.deleteEntry('audience');
50+
});
51+
52+
it('deletes the entry', function () {
53+
expect(cache.getEntry('audience')).to.not.exist;
54+
});
55+
});
56+
57+
describe('#getEntry', function () {
58+
const cache = new AzureTokenCache();
59+
60+
before(function () {
61+
cache.addEntry('audience1', tokenResultWithExpiration);
62+
cache.addEntry('audience2', tokenResultWithExpiration);
63+
});
64+
65+
context('when there is a matching entry', function () {
66+
it('returns the entry', function () {
67+
expect(cache.getEntry('audience1')).to.equal(tokenResultWithExpiration);
68+
});
69+
});
70+
71+
context('when there is no matching entry', function () {
72+
it('returns undefined', function () {
73+
expect(cache.getEntry('audience')).to.equal(undefined);
74+
});
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)