Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Support for silent retrieval of tokens from Token Store in Direct Line Speech scenarios #1459

Merged
merged 2 commits into from
May 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public class AuthenticationResponses : IResponseIdCollection
public const string AuthProvidersPrompt = "AuthProvidersPrompt";
public const string ConfiguredAuthProvidersPrompt = "ConfiguredAuthProvidersPrompt";
public const string ErrorMessageAuthFailure = "ErrorMessageAuthFailure";
public const string NoLinkedAccount = "NoLinkedAccount";
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,14 @@
}
],
"inputHint": "acceptingInput"
},
"NoLinkedAccount": {
"replies": [
{
"text": "A token could not be retrieved for {authType}, please link your account to your Assistant and try again",
"speak": "A token could not be retrieved for {authType}, please link your account to your Assistant and try again"
}
],
"inputHint": "acceptingInput"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,14 @@
}
],
"inputHint": "expectingInput"
},
"NoLinkedAccount": {
"replies": [
{
"text": "无法为 {authType} 检索令牌, 请将您的帐户链接到您的助手, 然后重试",
"speak": "无法为 {authType} 检索令牌, 请将您的帐户链接到您的助手, 然后重试"
}
],
"inputHint": "acceptingInput"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Choices;
using Microsoft.Bot.Builder.Solutions.Responses;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema;
using Microsoft.Rest.Serialization;

Expand Down Expand Up @@ -105,6 +107,51 @@ private async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepCon
{
return await stepContext.BeginDialogAsync(DialogIds.RemoteAuthPrompt).ConfigureAwait(false);
}
else if (!string.IsNullOrEmpty(stepContext.Context.Activity.ChannelId) && stepContext.Context.Activity.ChannelId == "directlinespeech")
{
// Speech channel doesn't support OAuthPrompt./OAuthCards so we rely on tokens being set by the Linked Accounts technique
// Therefore we don't use OAuthPrompt and instead attempt to directly retrieve the token from the store.
if (stepContext.Context.Activity.From == null || string.IsNullOrWhiteSpace(stepContext.Context.Activity.From.Id))
{
throw new ArgumentNullException("Missing From or From.Id which is required for token retrieval.");
}

var connectorClient = stepContext.Context.TurnState.Get<IConnectorClient>();
if (connectorClient == null)
{
throw new InvalidOperationException("An IConnectorClient is required in TurnState for this operation.");
}

var client = new OAuthClient(new Uri(OAuthClientConfig.OAuthEndpoint), connectorClient.Credentials);

// Attempt to retrieve the token directly, we can't prompt the user for which Token to use so go with the first
// Moving forward we expect to have a "default" choice as part of Linked Accounts,.
var tokenResponse = await client.UserToken.GetTokenWithHttpMessagesAsync(
stepContext.Context.Activity.From.Id,
_authenticationConnections.First().Name,
stepContext.Context.Activity.ChannelId,
null,
null,
canellationToken).ConfigureAwait(false);

if (tokenResponse != null && tokenResponse.Body != null && !string.IsNullOrEmpty(tokenResponse.Body.Token))
{
var providerTokenResponse = await CreateProviderTokenResponseAsync(stepContext.Context, tokenResponse.Body).ConfigureAwait(false);
return await stepContext.EndDialogAsync(providerTokenResponse).ConfigureAwait(false);
}
else
{
TelemetryClient.TrackEvent("DirectLineSpeechTokenRetrievalFailure");

var noLinkedAccountResponse = _responseManager.GetResponse(
AuthenticationResponses.NoLinkedAccount,
new StringDictionary() { { "authType", _authenticationConnections.First().Name } });

await stepContext.Context.SendActivityAsync(noLinkedAccountResponse).ConfigureAwait(false);

return new DialogTurnResult(DialogTurnStatus.Cancelled);
}
}
else
{
if (localAuthConfigured)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
</ItemGroup>

<ItemGroup>
<Compile Update="Authentication\AuthenticationResponses.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>AuthenticationResponses.tt</DependentUpon>
</Compile>
<Compile Update="Resources\CommonStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand All @@ -77,5 +82,17 @@
<LastGenOutput>CommonStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<None Update="Authentication\AuthenticationResponses.tt">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>AuthenticationResponses.cs</LastGenOutput>
</None>
</ItemGroup>

<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

</Project>