Skip to content

Commit

Permalink
port: [#4465][#6560] Allow TokenCredential authentication in CosmosDb…
Browse files Browse the repository at this point in the history
…PartitionedStorage (#4473)

* add tokenCredential authentication to cosmosDB

* fix ts issues with new version

* fix pipelines issues

* add EOF

---------

Co-authored-by: JhontSouth <jhonatan.sandoval@southworks.com>
  • Loading branch information
ceciliaavila and JhontSouth authored May 8, 2023
1 parent b110344 commit 192d4b2
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 39 deletions.
2 changes: 1 addition & 1 deletion libraries/botbuilder-azure-blobs/src/ignoreError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type IgnoreError = (err: Error) => boolean;
export async function ignoreError<T>(promise: Promise<T>, ignore: IgnoreError): Promise<T | null> {
try {
return await promise;
} catch (err) {
} catch (err: any) {
if (!ignore(err)) {
throw err;
} else {
Expand Down
2 changes: 2 additions & 0 deletions libraries/botbuilder-azure/etc/botbuilder-azure.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CosmosClientOptions } from '@azure/cosmos';
import { PagedResult } from 'botbuilder';
import { Storage as Storage_2 } from 'botbuilder';
import { StoreItems } from 'botbuilder';
import { TokenCredential } from '@azure/core-auth';
import { TranscriptInfo } from 'botbuilder';
import { TranscriptStore } from 'botbuilder';

Expand Down Expand Up @@ -64,6 +65,7 @@ export interface CosmosDbPartitionedStorageOptions {
cosmosDbEndpoint?: string;
databaseId: string;
keySuffix?: string;
tokenCredential?: TokenCredential;
}

// @public (undocumented)
Expand Down
3 changes: 2 additions & 1 deletion libraries/botbuilder-azure/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
}
},
"dependencies": {
"@azure/cosmos": "^3.3.1",
"@azure/cosmos": "3.10.0",
"@azure/core-auth": "^1.1.3",
"azure-storage": "2.10.7",
"botbuilder": "4.1.6",
"lodash": "^4.17.20",
Expand Down
34 changes: 26 additions & 8 deletions libraries/botbuilder-azure/src/cosmosDbPartitionedStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Container, CosmosClient, CosmosClientOptions } from '@azure/cosmos';
import { CosmosDbKeyEscape } from './cosmosDbKeyEscape';
import { DoOnce } from './doOnce';
import { Storage, StoreItems } from 'botbuilder';
import { TokenCredential } from '@azure/core-auth';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const pjson: Record<'name' | 'version', string> = require('../package.json');
Expand Down Expand Up @@ -67,6 +68,10 @@ export interface CosmosDbPartitionedStorageOptions {
* compatibilityMode cannot be true if keySuffix is used.
*/
compatibilityMode?: boolean;
/**
* The authentication tokenCredential for Cosmos DB.
*/
tokenCredential?: TokenCredential;
}

//Internal data structure for storing items in a CosmosDB Collection.
Expand Down Expand Up @@ -143,8 +148,12 @@ export class CosmosDbPartitionedStorage implements Storage {
throw new ReferenceError('cosmosDbEndpoint for CosmosDB is required.');
}
cosmosDbStorageOptions.authKey ??= cosmosClientOptions?.key;
if (!cosmosDbStorageOptions.authKey && !cosmosClientOptions?.tokenProvider) {
throw new ReferenceError('authKey for CosmosDB is required.');
if (
!cosmosDbStorageOptions.authKey &&
!cosmosClientOptions?.tokenProvider &&
!cosmosDbStorageOptions.tokenCredential
) {
throw new ReferenceError('authKey or tokenCredential for CosmosDB is required.');
}
if (!cosmosDbStorageOptions.databaseId) {
throw new ReferenceError('databaseId is for CosmosDB required.');
Expand Down Expand Up @@ -322,12 +331,21 @@ export class CosmosDbPartitionedStorage implements Storage {
async initialize(): Promise<void> {
if (!this.container) {
if (!this.client) {
this.client = new CosmosClient({
endpoint: this.cosmosDbStorageOptions.cosmosDbEndpoint,
key: this.cosmosDbStorageOptions.authKey,
userAgentSuffix: `${pjson.name} ${pjson.version}`,
...this.cosmosDbStorageOptions.cosmosClientOptions,
});
if (this.cosmosDbStorageOptions.tokenCredential) {
this.client = new CosmosClient({
endpoint: this.cosmosDbStorageOptions.cosmosDbEndpoint,
aadCredentials: this.cosmosDbStorageOptions.tokenCredential,
userAgentSuffix: `${pjson.name} ${pjson.version}`,
...this.cosmosDbStorageOptions.cosmosClientOptions,
});
} else {
this.client = new CosmosClient({
endpoint: this.cosmosDbStorageOptions.cosmosDbEndpoint,
key: this.cosmosDbStorageOptions.authKey,
userAgentSuffix: `${pjson.name} ${pjson.version}`,
...this.cosmosDbStorageOptions.cosmosClientOptions,
});
}
}
const dbAndContainerKey = `${this.cosmosDbStorageOptions.databaseId}-${this.cosmosDbStorageOptions.containerId}`;
this.container = await _doOnce.waitFor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ describe('CosmosDbPartitionedStorage - Constructor Tests', function () {
);
});

it('throws when no authKey provided', function () {
it('throws when no authKey or tokenCredential provided', function () {
const noAuthKey = getSettings();
noAuthKey.authKey = null;
assert.throws(
() => new CosmosDbPartitionedStorage(noAuthKey),
ReferenceError('authKey for CosmosDB is required.')
ReferenceError('authKey or tokenCredential for CosmosDB is required.')
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('ServiceCollection', function () {
services.addFactory<number[]>('values', (values = [1]) => values.concat(2));
services.composeFactory<number[]>('values', (values) => values.concat(3));

const { values } = services.makeInstances();
const { values } = services.makeInstances<{ values: number[] }>();
assert.deepStrictEqual(values, [1, 2, 3]);
});

Expand All @@ -69,7 +69,7 @@ describe('ServiceCollection', function () {
services.composeFactory<number[]>('values', (values) => values.concat(2));
services.composeFactory<number[]>('values', (values) => values.concat(3));

const { values } = services.makeInstances();
const { values } = services.makeInstances<{ values: number[] }>();
assert.deepStrictEqual(values, [1, 2, 3]);
});
});
Expand All @@ -95,8 +95,7 @@ describe('ServiceCollection', function () {

it('optionally fully reconstructs dependencies', function () {
const services = makeServiceCollection();

const { foo, bar, baz } = services.makeInstances();
const { foo, bar, baz } = services.makeInstances<{ foo: Foo; bar: Bar; baz: Baz }>();
assert.ok(foo);
assert.ok(bar);
assert.ok(baz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export function makeTriggers(
res.status(200);
res.set('Content-Type', contentType);
res.end(contents);
} catch (err) {
} catch (err: any) {
if (err.message.includes('ENOENT')) {
return res.status(404).end();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export async function makeApp(
await adapter.process(req, res, async (turnContext) => {
await bot.run(turnContext);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err, res);
}
});
Expand Down Expand Up @@ -173,7 +173,7 @@ export async function makeApp(
await adapter.process(req, res, async (turnContext) => {
await bot.run(turnContext);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err, res);
}
});
Expand All @@ -200,7 +200,7 @@ export async function makeApp(
await adapter.process(req, socket, head, async (context) => {
await bot.run(context);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export async function makeServer(
await adapter.process(req, res, async (turnContext) => {
await bot.run(turnContext);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err, res);
}
});
Expand Down Expand Up @@ -169,7 +169,7 @@ export async function makeServer(
await adapter.process(req, res, async (turnContext) => {
await bot.run(turnContext);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err, res);
}
});
Expand Down Expand Up @@ -197,7 +197,7 @@ export async function makeServer(
await adapter.process(req, socket, head, async (context) => {
await bot.run(context);
});
} catch (err) {
} catch (err: any) {
return errorHandler(err);
}
});
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-dialogs-adaptive-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ async function addSettingsBotComponents(services: ServiceCollection, configurati
const botComponent = await loadBotComponent(name);

botComponent.configureServices(services, configuration.bind([settingsPrefix ?? name]));
} catch (error) {
} catch (error: any) {
loadErrors.push({ error, name });
}
}
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-stdlib/src/retry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function retry<T>(
try {
// Note: return await intentional so we can catch errors
return await promise(n);
} catch (err) {
} catch (err: any) {
maybeError = err;

await new Promise((resolve) => setTimeout(resolve, delay));
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@
"source-map-support": "^0.5.19",
"sponge": "^0.1.0",
"tinyify": "^3.0.0",
"ts-node": "^9.0.0",
"ts-node": "^10.0.0",
"typedoc": "^0.19.2",
"typedoc-plugin-external-module-name": "^4.0.3",
"typedoc-plugin-markdown": "^3.0.11",
"typescript": "^4.0.5",
"typescript": "^4.1.0",
"wsrun": "^5.2.4"
},
"nyc": {
Expand Down
Loading

0 comments on commit 192d4b2

Please sign in to comment.