Skip to content

Commit b0c1836

Browse files
stevengumjohnataylor
authored andcommitted
Cherry-pick commits from 4.7 branch to master (#1502)
* add vendor/ to botbuilder-dialogs incl. files (#1493) * fix casing on relative import references for NamedPipeTransport (#1494) * fix casing in WebSocketServer (#1495) * fix more casing issues (#1496) * fix auth bug, streaming dependencies, add tests (#1498)
1 parent ac06ba2 commit b0c1836

File tree

17 files changed

+83
-49
lines changed

17 files changed

+83
-49
lines changed

libraries/botbuilder-dialogs/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
},
4747
"files": [
4848
"/lib",
49-
"/src"
49+
"/src",
50+
"/vendor"
5051
]
5152
}

libraries/botbuilder/src/botFrameworkAdapter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,8 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
10851085
if (!credentials) throw new Error('invalid credentials');
10861086

10871087
let client: ConnectorClient = context.turnState.get(this.ConnectorClientKey);
1088-
if (!client) {
1088+
// Inspect the retrieved client to confirm that the serviceUrl is correct, if it isn't, create a new one.
1089+
if (!client || client['baseUri'] !== serviceUrl) {
10891090
client = this.createConnectorClientInternal(serviceUrl, credentials);
10901091
}
10911092

@@ -1098,7 +1099,7 @@ export class BotFrameworkAdapter extends BotAdapter implements IUserTokenProvide
10981099
* @param appId
10991100
* @param oAuthScope
11001101
*/
1101-
protected async buildCredentials(appId: string, oAuthScope: string = ''): Promise<AppCredentials> {
1102+
protected async buildCredentials(appId: string, oAuthScope?: string): Promise<AppCredentials> {
11021103
// There is no cache for AppCredentials in JS as opposed to C#.
11031104
// Instead of retrieving an AppCredentials from the Adapter instance, generate a new one
11041105
const appPassword = await this.credentialsProvider.getAppPassword(appId);

libraries/botbuilder/src/botFrameworkHttpClient.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,11 @@ export class BotFrameworkHttpClient {
110110

111111
const appPassword = await this.credentialProvider.getAppPassword(appId);
112112
if (JwtTokenValidation.isGovernment(this.channelService)) {
113-
appCredentials = new MicrosoftAppCredentials(appId, appPassword, this.channelService);
113+
appCredentials = new MicrosoftAppCredentials(appId, appPassword, this.channelService, oAuthScope);
114114
appCredentials.oAuthEndpoint = GovernmentConstants.ToChannelFromBotLoginUrl;
115115
appCredentials.oAuthScope = GovernmentConstants.ToChannelFromBotOAuthScope;
116116
} else {
117-
appCredentials = new MicrosoftAppCredentials(appId, appPassword, this.channelService);
118-
appCredentials.oAuthScope = !oAuthScope ? AuthenticationConstants.ToChannelFromBotOAuthScope : oAuthScope;
117+
appCredentials = new MicrosoftAppCredentials(appId, appPassword, this.channelService, oAuthScope);
119118
}
120119

121120
// Cache the credentials for later use

libraries/botbuilder/src/skills/skillHandler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ export class SkillHandler extends ChannelServiceHandler {
148148
const adapter: BotFrameworkAdapter = (context.adapter as BotFrameworkAdapter);
149149
// Cache the ClaimsIdentity and ConnectorClient on the context so that it's available inside of the bot's logic.
150150
context.turnState.set(adapter.BotIdentityKey, claimsIdentity);
151-
const client = await adapter.createConnectorClientWithIdentity(activity.serviceUrl, claimsIdentity);
152-
context.turnState.set(adapter.ConnectorClientKey, client);
153151
context.turnState.set(this.SkillConversationReferenceKey, skillConversationReference);
152+
activity = TurnContext.applyConversationReference(activity, conversationReference) as Activity;
153+
const client = adapter.createConnectorClient(activity.serviceUrl);
154+
context.turnState.set(adapter.ConnectorClientKey, client);
154155

155-
TurnContext.applyConversationReference(activity, conversationReference);
156156
context.activity.id = replyToActivityId;
157157
switch (activity.type) {
158158
case ActivityTypes.EndOfConversation:

libraries/botbuilder/src/streaming/streamingHttpClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Licensed under the MIT License.
77
*/
88

9-
import { WebResource, HttpOperationResponse, HttpClient } from 'botframework-connector/node_modules/@azure/ms-rest-js';
9+
import { WebResource, HttpOperationResponse, HttpClient } from '@azure/ms-rest-js';
1010
import { IStreamingTransportServer, StreamingRequest } from 'botframework-streaming';
1111

1212
export class StreamingHttpClient implements HttpClient {

libraries/botbuilder/tests/botFrameworkAdapter.test.js

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const assert = require('assert');
2-
const { TurnContext } = require('botbuilder-core');
2+
const { ActivityTypes, TurnContext } = require('botbuilder-core');
33
const connector = require('botframework-connector');
4-
const { AuthenticationConstants, CertificateAppCredentials } = require('botframework-connector');
4+
const { AuthenticationConstants, CertificateAppCredentials, ConnectorClient, MicrosoftAppCredentials } = require('botframework-connector');
55
const { BotFrameworkAdapter } = require('../');
66

77
const reference = {
@@ -257,13 +257,25 @@ describe(`BotFrameworkAdapter`, function () {
257257
});
258258
});
259259

260-
it(`should createConnectorClient().`, function (done) {
261-
const req = new MockRequest(incomingMessage);
262-
const adapter = new AdapterUnderTest();
263-
const client = adapter.testCreateConnectorClient(reference.serviceUrl);
264-
assert(client, `client not returned.`);
265-
assert(client.conversations, `invalid client returned.`);
266-
done();
260+
describe('get/create ConnectorClient methods', () => {
261+
it(`should createConnectorClient().`, function (done) {
262+
const req = new MockRequest(incomingMessage);
263+
const adapter = new AdapterUnderTest();
264+
const client = adapter.testCreateConnectorClient(reference.serviceUrl);
265+
assert(client, `client not returned.`);
266+
assert(client.conversations, `invalid client returned.`);
267+
done();
268+
});
269+
270+
it('getOrCreateConnectorClient should create a new client if the cached serviceUrl does not match the provided one', () => {
271+
const adapter = new BotFrameworkAdapter();
272+
const context = new TurnContext(adapter, { type: ActivityTypes.Message, text: 'hello', serviceUrl: 'http://bing.com' });
273+
const cc = new ConnectorClient(new MicrosoftAppCredentials('', ''), {baseUri: 'http://bing.com'});
274+
context.turnState.set(adapter.ConnectorClientKey, cc);
275+
276+
const client = adapter.getOrCreateConnectorClient(context, 'https://botframework.com', adapter.credentials);
277+
assert.notEqual(client.baseUri, cc.baseUri);
278+
});
267279
});
268280

269281
it(`should processActivity().`, function (done) {
@@ -732,15 +744,15 @@ describe(`BotFrameworkAdapter`, function () {
732744
});
733745

734746
// This unit test doesn't work anymore because client.UserAgentInfo was removed, so we can't inspect the user agent string
735-
// it(`should create a User-Agent header with the same info as the host machine.`, function (done) {
736-
// const adapter = new BotFrameworkAdapter();
737-
// const client = adapter.createConnectorClient('https://example.com');
738-
// //const userAgentHeader = client.userAgentInfo.value;
739-
// const pjson = require('../package.json');
740-
// const userAgent = 'Microsoft-BotFramework/3.1 BotBuilder/' + pjson.version + ' (Node.js,Version=' + process.version + '; ' + os.type() + ' ' + os.release() + '; ' + os.arch() + ')';
741-
// // assert(userAgentHeader.includes(userAgent), `ConnectorClient doesn't have user-agent header created by BotFrameworkAdapter or header is incorrect.`);
742-
// done();
743-
// });
747+
xit(`should create a User-Agent header with the same info as the host machine.`, function (done) {
748+
const adapter = new BotFrameworkAdapter();
749+
const client = adapter.createConnectorClient('https://example.com');
750+
//const userAgentHeader = client.userAgentInfo.value;
751+
const pjson = require('../package.json');
752+
const userAgent = 'Microsoft-BotFramework/3.1 BotBuilder/' + pjson.version + ' (Node.js,Version=' + process.version + '; ' + os.type() + ' ' + os.release() + '; ' + os.arch() + ')';
753+
// assert(userAgentHeader.includes(userAgent), `ConnectorClient doesn't have user-agent header created by BotFrameworkAdapter or header is incorrect.`);
754+
done();
755+
});
744756

745757
it(`should set openIdMetadata property on ChannelValidation`, function (done) {
746758
const testEndpoint = "http://rainbows.com";

libraries/botframework-connector/src/auth/appCredentials.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,32 @@ export abstract class AppCredentials implements msrest.ServiceClientCredentials
3030
public appId: string;
3131

3232
public oAuthEndpoint: string;
33-
public oAuthScope: string = AuthenticationConstants.ToBotFromChannelTokenIssuer;
34-
public readonly tokenCacheKey: string;
33+
private _oAuthScope: string;
34+
public tokenCacheKey: string;
3535
protected refreshingToken: Promise<adal.TokenResponse> | null = null;
3636
protected readonly authenticationContext: adal.AuthenticationContext;
3737

38-
constructor(appId: string, channelAuthTenant?: string) {
38+
constructor(appId: string, channelAuthTenant?: string, oAuthScope: string = AuthenticationConstants.ToBotFromChannelTokenIssuer) {
3939
this.appId = appId;
4040
const tenant = channelAuthTenant && channelAuthTenant.length > 0
4141
? channelAuthTenant
4242
: AuthenticationConstants.DefaultChannelAuthTenant;
4343
this.oAuthEndpoint = AuthenticationConstants.ToChannelFromBotLoginUrlPrefix + tenant;
44-
this.tokenCacheKey = `${ appId }${ this.oAuthScope }-cache`;
44+
this.oAuthScope = oAuthScope;
4545
// aadApiVersion is set to '1.5' to avoid the "spn:" concatenation on the audience claim
4646
// For more info, see https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/issues/128
4747
this.authenticationContext = new adal.AuthenticationContext(this.oAuthEndpoint, true, undefined, '1.5');
4848
}
4949

50+
public get oAuthScope(): string {
51+
return this._oAuthScope
52+
}
53+
54+
public set oAuthScope(value: string) {
55+
this._oAuthScope = value;
56+
this.tokenCacheKey = `${ this.appId }${ this.oAuthScope }-cache`;
57+
}
58+
5059
/**
5160
* Adds the host of service url to trusted hosts.
5261
* If expiration time is not provided, the expiration date will be current (utc) date + 1 day.

libraries/botframework-connector/src/auth/certificateAppCredentials.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export class CertificateAppCredentials extends AppCredentials {
1616
public certificateThumbprint: string;
1717
public certificatePrivateKey: string;
1818

19-
constructor(appId: string, certificateThumbprint: string, certificatePrivateKey: string, channelAuthTenant?: string) {
20-
super(appId, channelAuthTenant);
19+
constructor(appId: string, certificateThumbprint: string, certificatePrivateKey: string, channelAuthTenant?: string, oAuthScope?: string) {
20+
super(appId, channelAuthTenant, oAuthScope);
2121
this.certificateThumbprint = certificateThumbprint;
2222
this.certificatePrivateKey = certificatePrivateKey;
2323
}

libraries/botframework-connector/src/auth/microsoftAppCredentials.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@ export class MicrosoftAppCredentials extends AppCredentials {
1616
public appPassword: string;
1717

1818
constructor(appId: string, appPassword: string, channelAuthTenant?: string, oAuthScope?: string) {
19-
super(appId, channelAuthTenant);
19+
super(appId, channelAuthTenant, oAuthScope);
2020
this.appPassword = appPassword;
21-
22-
// AppCredentials.oAuthScope has an initial an initial value of AuthenticationConstants.ToBotFromChannelTokenIssuer,
23-
// Only change it if there is an actual value provided in the constructor for MicrosoftAppCredentials.
24-
this.oAuthScope = oAuthScope ? oAuthScope : this.oAuthScope;
2521
}
2622

2723
protected async refreshToken(): Promise<adal.TokenResponse> {

libraries/botframework-connector/tests/appCredentials.test.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,34 @@ describe('AppCredentials', () => {
3232
strictEqual(certCreds.certificatePrivateKey, CERT_KEY);
3333

3434
const msAppCreds = new MicrosoftAppCredentials(APP_ID, APP_PASSWORD);
35-
strictEqual(msAppCreds.appId, '2cd87869-38a0-4182-9251-d056e8f0ac24');
35+
strictEqual(msAppCreds.appId, APP_ID);
3636
strictEqual(msAppCreds.appPassword, APP_PASSWORD);
3737
});
3838

3939
describe('MicrosoftAppCredentials', () => {
4040
it('should set oAuthScope when passed in the constructor', () => {
4141
const oAuthScope = 'oAuthScope';
42-
const tokenGenerator = new MicrosoftAppCredentials('2cd87869-38a0-4182-9251-d056e8f0ac24', undefined, undefined, oAuthScope);
42+
const tokenGenerator = new MicrosoftAppCredentials(APP_ID, undefined, undefined, oAuthScope);
4343
strictEqual(tokenGenerator.oAuthScope, oAuthScope);
4444
});
45+
46+
it('should set update the tokenCacheKey when oAuthScope is set after construction', () => {
47+
const tokenGenerator = new MicrosoftAppCredentials(APP_ID);
48+
strictEqual(tokenGenerator.tokenCacheKey, `${APP_ID}${AuthenticationConstants.ToBotFromChannelTokenIssuer}-cache`);
49+
50+
const oAuthScope = 'oAuthScope';
51+
tokenGenerator.oAuthScope = oAuthScope;
52+
strictEqual(tokenGenerator.tokenCacheKey, `${APP_ID}${oAuthScope}-cache`);
53+
54+
/* CertificateAppCredentials */
55+
const certCreds = new CertificateAppCredentials(APP_ID, CERT_THUMBPRINT, CERT_KEY);
56+
strictEqual(certCreds.tokenCacheKey, `${APP_ID}${AuthenticationConstants.ToBotFromChannelTokenIssuer}-cache`);
57+
certCreds.oAuthScope = oAuthScope;
58+
strictEqual(certCreds.tokenCacheKey, `${APP_ID}${oAuthScope}-cache`);
59+
});
60+
4561
it('should fail to get a token with an appId and no appPassword', async () => {
46-
const tokenGenerator = new MicrosoftAppCredentials('2cd87869-38a0-4182-9251-d056e8f0ac24');
62+
const tokenGenerator = new MicrosoftAppCredentials(APP_ID);
4763
try {
4864
await tokenGenerator.getToken(true);
4965
fail('Should not have successfully retrieved token.');

0 commit comments

Comments
 (0)