Skip to content

Commit

Permalink
migrate c# change in for adding oauth app credentials as a parameter (#…
Browse files Browse the repository at this point in the history
…1697)

* migrate .net change in for adding oauth app credentials as a parameter

* rename variable

* change turn state key name

* fix use ternary operator

* use CredentialTokenProvider interface that extends UserTokenProvider interface

* remove unused comments

* correct the credentialTokenProvider interface path

* fix import

* fix the dependency chain

* fix parameter name

* fix comments

* fix tests

* fix token resolve test

* fix test

* make webResource interface

* cleanup new interface names

* rename AppCredentialsProvider to AppCredentials

* add back newline

Co-authored-by: Steven Ickman <stevenic@microsoft.com>
Co-authored-by: Steven Gum <14935595+stevengum@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 28, 2020
1 parent 05ead6e commit 0d2a4ed
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 44 deletions.
27 changes: 27 additions & 0 deletions libraries/botbuilder-core/src/appCredentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @module botbuilder-core
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

/**
* Internal interface representing the "WebResource" from @azure/ms-rest-js@1.2.6
*/
interface WebResource {}

/**
* AppCredentials
* @remarks
* Runtime-agnostic interface representing "ServiceClientCredentials" from @azure/ms-rest-js@1.2.6
*/
export interface AppCredentials {
/**
* Signs a request with the Authentication header.
*
* @param {WebResource} webResource The WebResource/request to be signed.
* @returns {Promise<WebResource>} The signed request object;
*/
signRequest(webResource: WebResource): Promise<WebResource>;
}
49 changes: 49 additions & 0 deletions libraries/botbuilder-core/src/credentialTokenProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @module botbuilder-core
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { AppCredentials } from './appCredentials';
import { IUserTokenProvider } from './userTokenProvider';
import { TurnContext } from './turnContext';
import { TokenResponse } from 'botframework-schema';

export interface CredentialTokenProvider extends IUserTokenProvider {
/**
* Retrieves the OAuth token for a user that is in a sign-in flow.
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param magicCode (Optional) Optional user entered code to validate.
*/
getUserToken(context: TurnContext, connectionName: string, magicCode?: string, appCredentials?: AppCredentials): Promise<TokenResponse>;

/**
* Signs the user out with the token server.
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param userId User id of user to sign out.
* @param oAuthAppCredentials AppCredentials for OAuth.
*/
signOutUser(context: TurnContext, connectionName: string, userId?: string, appCredentials?: AppCredentials): Promise<void>;

/**
* Gets a signin link from the token server that can be sent as part of a SigninCard.
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param oAuthAppCredentials AppCredentials for OAuth.
*/
getSignInLink(context: TurnContext, connectionName: string, appCredentials?: AppCredentials): Promise<string>;

/**
* Signs the user out with the token server.
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param oAuthAppCredentials AppCredentials for OAuth.
*/
getAadTokens(context: TurnContext, connectionName: string, resourceUrls: string[], appCredentials?: AppCredentials): Promise<{
[propertyName: string]: TokenResponse;
}>;
}
2 changes: 2 additions & 0 deletions libraries/botbuilder-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ export * from './turnContext';
export * from './userState';
export * from './userTokenProvider';
export * from './userTokenSettings';
export * from './appCredentials';
export * from './credentialTokenProvider';
4 changes: 2 additions & 2 deletions libraries/botbuilder-core/src/userTokenProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ export interface IUserTokenProvider {
* Signs the user out with the token server.
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param userId User id of user to sign out.
*/
signOutUser(context: TurnContext, connectionName: string): Promise<void>;
signOutUser(context: TurnContext, connectionName: string, userId?: string): Promise<void>;

/**
* Gets a signin link from the token server that can be sent as part of a SigninCard.
Expand All @@ -44,4 +45,3 @@ export interface IUserTokenProvider {
[propertyName: string]: TokenResponse;
}>;
}

8 changes: 3 additions & 5 deletions libraries/botbuilder-core/src/userTokenSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
/**
* Provides details for token polling.
*/
export interface TokenPollingSettings
{
export interface TokenPollingSettings {
/**
* Polling timeout time in milliseconds. This is equivalent to login flow timeout.
*/
Expand All @@ -30,13 +29,12 @@ export const OAuthLoginTimeoutKey: string = 'loginTimeout';
/**
* Name of the token polling settings key.
*/
export const TokenPollingSettingsKey: string = "tokenPollingSettings";

export const TokenPollingSettingsKey: string = 'tokenPollingSettings';

/**
* Default amount of time an OAuthCard will remain active (clickable and actively waiting for a token).
* After this time:
* (1) the OAuthCard will not allow the user to click on it.
* (2) any polling triggered by the OAuthCard will stop.
*/
export const OAuthLoginTimeoutMsValue: number = 900000;
export const OAuthLoginTimeoutMsValue: number = 900000;
22 changes: 13 additions & 9 deletions libraries/botbuilder-dialogs/src/prompts/oauthPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { Activity, ActivityTypes, Attachment, CardFactory, Channels, InputHints, MessageFactory, OAuthLoginTimeoutKey, TokenResponse, TurnContext, IUserTokenProvider, OAuthCard, ActionTypes, } from 'botbuilder-core';
import { Activity, ActivityTypes, AppCredentials, Attachment, CardFactory, Channels, InputHints, MessageFactory, OAuthLoginTimeoutKey, TokenResponse, TurnContext, CredentialTokenProvider, OAuthCard, ActionTypes, } from 'botbuilder-core';
import { Dialog, DialogTurnResult } from '../dialog';
import { DialogContext } from '../dialogContext';
import { PromptOptions, PromptRecognizerResult, PromptValidator } from './prompt';
Expand All @@ -15,6 +15,11 @@ import { isSkillClaim } from './skillsHelpers';
* Settings used to configure an `OAuthPrompt` instance.
*/
export interface OAuthPromptSettings {
/**
* AppCredentials for OAuth.
*/
oAuthAppCredentials: AppCredentials;

/**
* Name of the OAuth connection being used.
*/
Expand Down Expand Up @@ -104,7 +109,6 @@ export interface OAuthPromptSettings {
* ```
*/
export class OAuthPrompt extends Dialog {

/**
* Creates a new OAuthPrompt instance.
* @param dialogId Unique ID of the dialog within its parent `DialogSet` or `ComponentDialog`.
Expand Down Expand Up @@ -201,9 +205,9 @@ export class OAuthPrompt extends Dialog {
}

// Get the token and call validator
const adapter: IUserTokenProvider = context.adapter as IUserTokenProvider;
const adapter: CredentialTokenProvider = context.adapter as CredentialTokenProvider;

return await adapter.getUserToken(context, this.settings.connectionName, code);
return await adapter.getUserToken(context, this.settings.connectionName, code, this.settings.oAuthAppCredentials);
}

/**
Expand All @@ -228,9 +232,9 @@ export class OAuthPrompt extends Dialog {
}

// Sign out user
const adapter: IUserTokenProvider = context.adapter as IUserTokenProvider;
const adapter: CredentialTokenProvider = context.adapter as CredentialTokenProvider;

return adapter.signOutUser(context, this.settings.connectionName);
return adapter.signOutUser(context, this.settings.connectionName, null, this.settings.oAuthAppCredentials);
}

private async sendOAuthCardAsync(context: TurnContext, prompt?: string|Partial<Activity>): Promise<void> {
Expand All @@ -251,14 +255,14 @@ export class OAuthPrompt extends Dialog {
let cardActionType = ActionTypes.Signin;
let link: string;
if (OAuthPrompt.isFromStreamingConnection(context.activity)) {
link = await (context.adapter as any).getSignInLink(context, this.settings.connectionName);
link = await (context.adapter as CredentialTokenProvider).getSignInLink(context, this.settings.connectionName, this.settings.oAuthAppCredentials);
} else {
// Retrieve the ClaimsIdentity from a BotFrameworkAdapter. For more information see
// https://github.com/microsoft/botbuilder-js/commit/b7932e37bb6e421985d5ce53edd9e82af6240a63#diff-3e3af334c0c6adf4906ee5e2a23beaebR250
const identity = context.turnState.get((context.adapter as any).BotIdentityKey);
if (identity && isSkillClaim(identity.claims)) {
// Force magic code for Skills (to be addressed in R8)
link = await (context.adapter as any).getSignInLink(context, this.settings.connectionName);
link = await (context.adapter as CredentialTokenProvider).getSignInLink(context, this.settings.connectionName, this.settings.oAuthAppCredentials);
cardActionType = ActionTypes.OpenUrl;
}
}
Expand All @@ -278,7 +282,7 @@ export class OAuthPrompt extends Dialog {
const cards: Attachment[] = msg.attachments.filter((a: Attachment) => a.contentType === CardFactory.contentTypes.signinCard);
if (cards.length === 0) {
// Append signin card
const link: any = await (context.adapter as any).getSignInLink(context, this.settings.connectionName);
const link: any = await (context.adapter as CredentialTokenProvider).getSignInLink(context, this.settings.connectionName, this.settings.oAuthAppCredentials);
msg.attachments.push(CardFactory.signinCard(
this.settings.title,
link,
Expand Down
Loading

0 comments on commit 0d2a4ed

Please sign in to comment.