-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(auth): add EntraId integration tests
- Add integration tests for token renewal and re-authentication flows - Update credentials provider to use uniqueId as username instead of account username - Add test utilities for loading Redis endpoint configurations - Split TypeScript configs into separate files for samples and integration tests
- Loading branch information
1 parent
ac972bd
commit 3af6f10
Showing
7 changed files
with
118 additions
and
6 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
packages/entraid/integration-tests/entraid-integration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { BasicAuth } from '@redis/authx'; | ||
import { createClient } from '@redis/client'; | ||
import { EntraIdCredentialsProviderFactory } from '../lib/entra-id-credentials-provider-factory'; | ||
import { strict as assert } from 'node:assert'; | ||
import { spy } from 'sinon'; | ||
import { randomUUID } from 'crypto'; | ||
import { loadFromJson } from '@redis/test-utils/lib/cae-client-testing' | ||
|
||
describe('EntraID Integration Tests', () => { | ||
|
||
it('should automatically re-authenticate when token is renewed', async () => { | ||
|
||
if (!process.env.REDIS_ENDPOINTS_CONFIG_PATH) { | ||
throw new Error('REDIS_ENDPOINTS_CONFIG_PATH environment variable must be set'); | ||
} | ||
if (!process.env.AZURE_CLIENT_ID) { | ||
throw new Error('AZURE_CLIENT_ID environment variable must be set'); | ||
} | ||
if (!process.env.AZURE_TENANT_ID) { | ||
throw new Error('AZURE_TENANT_ID environment variable must be set'); | ||
} | ||
if (!process.env.AZURE_CLIENT_SECRET) { | ||
throw new Error('AZURE_CLIENT_SECRET environment variable must be set'); | ||
} | ||
|
||
const endpoints = loadFromJson(process.env.REDIS_ENDPOINTS_CONFIG_PATH) | ||
const clientId = process.env.AZURE_CLIENT_ID; | ||
const tenantId = process.env.AZURE_TENANT_ID; | ||
const clientSecret = process.env.AZURE_CLIENT_SECRET; | ||
|
||
const entraidCredentialsProvider = EntraIdCredentialsProviderFactory.createForClientCredentials({ | ||
clientId: clientId, | ||
clientSecret: clientSecret, | ||
authorityConfig: { type: 'multi-tenant', tenantId: tenantId }, | ||
tokenManagerConfig: { | ||
expirationRefreshRatio: 0.001 | ||
} | ||
}); | ||
|
||
const client = createClient({ | ||
url: endpoints['standalone-entraid-acl'].endpoints[0], | ||
credentialsProvider: entraidCredentialsProvider | ||
}); | ||
|
||
const reAuthSpy = spy(client, <any>'reAuthenticate'); | ||
|
||
try { | ||
await client.connect(); | ||
|
||
const startTime = Date.now(); | ||
while (Date.now() - startTime < 200) { | ||
const key = randomUUID(); | ||
await client.set(key, 'value'); | ||
const value = await client.get(key); | ||
assert.equal(value, 'value'); | ||
await client.del(key); | ||
} | ||
|
||
assert(reAuthSpy.callCount >= 1, `reAuthenticate should have been called at least once, but was called ${reAuthSpy.callCount} times`); | ||
|
||
const uniqueCredentials = new Set( | ||
reAuthSpy.getCalls().map(call => { | ||
const creds = call.args[0] as BasicAuth; | ||
return `${creds.username}:${creds.password}`; | ||
}) | ||
); | ||
|
||
assert.equal( | ||
uniqueCredentials.size, | ||
reAuthSpy.callCount, | ||
`Expected ${reAuthSpy.callCount} different credentials, but got ${uniqueCredentials.size} unique credentials` | ||
); | ||
|
||
} finally { | ||
client.destroy(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"include": [ | ||
"./integration-tests/**/*.ts", | ||
"./lib/**/*.ts" | ||
], | ||
"compilerOptions": { | ||
"noEmit": true | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"include": [ | ||
"./samples/**/*.ts", | ||
"./lib/**/*.ts" | ||
], | ||
"compilerOptions": { | ||
"noEmit": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
interface RawRedisEndpoint { | ||
username?: string; | ||
password?: string; | ||
tls: boolean; | ||
endpoints: string[]; | ||
} | ||
|
||
type RedisEndpointsConfig = Record<string, RawRedisEndpoint>; | ||
|
||
export function loadFromJson(jsonString: string): RedisEndpointsConfig { | ||
try { | ||
return JSON.parse(jsonString) as RedisEndpointsConfig; | ||
} catch (error) { | ||
throw new Error(`Invalid JSON configuration: ${error}`); | ||
} | ||
} |