Support passing sas token url's for token service (#6449)
Co-authored-by: Swagat Mishra <swagatm@microsoft.com>
This commit is contained in:
Родитель
bc5d708320
Коммит
fe6f8489d0
|
@ -177,6 +177,7 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
},
|
||||
},
|
||||
TokenExchangeResource = signInResource.TokenExchangeResource,
|
||||
TokenPostResource = signInResource.TokenPostResource
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -810,7 +810,7 @@ namespace Microsoft.Bot.Builder.Adapters
|
|||
/// <param name="finalRedirect">A final redirect URL.</param>
|
||||
/// <param name="cancellationToken">The cancellationToken.</param>
|
||||
/// <returns>A SignInResource with the link and token exchange info.</returns>
|
||||
public Task<SignInResource> GetSignInResourceAsync(ITurnContext turnContext, AppCredentials oAuthAppCredentials, string connectionName, string userId, string finalRedirect = null, CancellationToken cancellationToken = default)
|
||||
public virtual Task<SignInResource> GetSignInResourceAsync(ITurnContext turnContext, AppCredentials oAuthAppCredentials, string connectionName, string userId, string finalRedirect = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(new SignInResource()
|
||||
{
|
||||
|
|
|
@ -57,6 +57,13 @@ namespace Microsoft.Bot.Schema
|
|||
[JsonProperty(PropertyName = "tokenExchangeResource")]
|
||||
public TokenExchangeResource TokenExchangeResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resource to directly post a token to token service.
|
||||
/// </summary>
|
||||
/// <value>The resource to directly post a token to token service.</value>
|
||||
[JsonProperty(PropertyName = "tokenPostResource")]
|
||||
public TokenPostResource TokenPostResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets action to use to perform signin.
|
||||
/// </summary>
|
||||
|
|
|
@ -44,6 +44,13 @@ namespace Microsoft.Bot.Schema
|
|||
[JsonProperty(PropertyName = "tokenExchangeResource")]
|
||||
public TokenExchangeResource TokenExchangeResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets additional properties that can be used for direct token posting operations.
|
||||
/// </summary>
|
||||
/// <value>The additional properties can be used for token posting operations.</value>
|
||||
[JsonProperty(PropertyName = "tokenPostResource")]
|
||||
public TokenPostResource TokenPostResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An initialization method that performs custom operations like setting defaults.
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.Bot.Schema
|
||||
{
|
||||
/// <summary>
|
||||
/// Response schema sent back from Bot Framework Token Service required to initiate a user token direct post.
|
||||
/// </summary>
|
||||
public partial class TokenPostResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TokenPostResource"/> class.
|
||||
/// </summary>
|
||||
public TokenPostResource()
|
||||
{
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the shared access signature url used to directly post a token to Bot Framework Token Service.
|
||||
/// </summary>
|
||||
/// <value>The URI.</value>
|
||||
[JsonProperty(PropertyName = "sasUrl")]
|
||||
#pragma warning disable CA1056 // Uri properties should not be strings
|
||||
public string SasUrl { get; set; }
|
||||
#pragma warning restore CA1056 // Uri properties should not be strings
|
||||
|
||||
partial void CustomInit();
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Bot.Connector;
|
||||
using Microsoft.Bot.Connector.Authentication;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
@ -15,14 +17,21 @@ using Xunit.Sdk;
|
|||
namespace Microsoft.Bot.Builder.Dialogs.Tests
|
||||
{
|
||||
public class OAuthPromptTests
|
||||
{
|
||||
{
|
||||
private const string UserId = "user-id";
|
||||
private const string ConnectionName = "connection-name";
|
||||
private const string ChannelId = "channel-id";
|
||||
private const string MagicCode = "888999";
|
||||
private const string Token = "token123";
|
||||
private const string ExchangeToken = "exch123";
|
||||
|
||||
|
||||
public static TheoryData<TestAdapter, bool> SasTestData =>
|
||||
new TheoryData<TestAdapter, bool>
|
||||
{
|
||||
{ new TestAdapter(), false },
|
||||
{ new SignInResourceAdapter(), true }
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void OAuthPromptWithEmptySettingsShouldFail()
|
||||
{
|
||||
|
@ -589,7 +598,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
|
|||
[InlineData(true, Channels.Msteams, true)] //Override: show link; ChannelRequiresSingInLink() returns true; Result: show link
|
||||
public async Task OAuthPromptSignInLinkSettingsCases(bool? showSignInLinkValue, string channelId, bool shouldHaveSignInLink)
|
||||
{
|
||||
var oAuthPromptSettings = new OAuthPromptSettings();
|
||||
var oAuthPromptSettings = new OAuthPromptSettings();
|
||||
oAuthPromptSettings.ShowSignInLink = showSignInLinkValue;
|
||||
|
||||
var convoState = new ConversationState(new MemoryStorage());
|
||||
|
@ -620,11 +629,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
|
|||
};
|
||||
await new TestFlow(adapter, botCallbackHandler)
|
||||
.Send(initialActivity)
|
||||
.AssertReply(activity =>
|
||||
{
|
||||
Assert.Single(((Activity)activity).Attachments);
|
||||
Assert.Equal(OAuthCard.ContentType, ((Activity)activity).Attachments[0].ContentType);
|
||||
var oAuthCard = (OAuthCard)((Activity)activity).Attachments[0].Content;
|
||||
.AssertReply(activity =>
|
||||
{
|
||||
Assert.Single(((Activity)activity).Attachments);
|
||||
Assert.Equal(OAuthCard.ContentType, ((Activity)activity).Attachments[0].ContentType);
|
||||
var oAuthCard = (OAuthCard)((Activity)activity).Attachments[0].Content;
|
||||
var cardAction = oAuthCard.Buttons[0];
|
||||
Assert.Equal(shouldHaveSignInLink, cardAction.Value != null);
|
||||
})
|
||||
|
@ -710,6 +719,55 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
|
|||
.StartTestAsync();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(SasTestData))]
|
||||
public async Task OAuthPromptSasUrlPresentInOAuthCard(TestAdapter testAdapter, bool containsSasurl)
|
||||
{
|
||||
var oAuthPromptSettings = new OAuthPromptSettings();
|
||||
|
||||
var convoState = new ConversationState(new MemoryStorage());
|
||||
var dialogState = convoState.CreateProperty<DialogState>("dialogState");
|
||||
|
||||
var adapter = testAdapter
|
||||
.Use(new AutoSaveStateMiddleware(convoState));
|
||||
|
||||
// Create new DialogSet
|
||||
var dialogs = new DialogSet(dialogState);
|
||||
dialogs.Add(new OAuthPrompt("OAuthPrompt", oAuthPromptSettings));
|
||||
|
||||
BotCallbackHandler botCallbackHandler = async (turnContext, cancellationToken) =>
|
||||
{
|
||||
var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);
|
||||
|
||||
var results = await dc.ContinueDialogAsync(cancellationToken);
|
||||
if (results.Status == DialogTurnStatus.Empty)
|
||||
{
|
||||
await dc.PromptAsync("OAuthPrompt", new PromptOptions(), cancellationToken: cancellationToken);
|
||||
}
|
||||
};
|
||||
|
||||
await new TestFlow(adapter, botCallbackHandler)
|
||||
.Send("hello")
|
||||
.AssertReply(activity =>
|
||||
{
|
||||
Assert.Single(((Activity)activity).Attachments);
|
||||
Assert.Equal(OAuthCard.ContentType, ((Activity)activity).Attachments[0].ContentType);
|
||||
var oAuthCard = (OAuthCard)((Activity)activity).Attachments[0].Content;
|
||||
if (containsSasurl)
|
||||
{
|
||||
Assert.NotNull(oAuthCard.TokenPostResource);
|
||||
Assert.NotNull(oAuthCard.TokenPostResource.SasUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(oAuthCard.TokenPostResource);
|
||||
}
|
||||
|
||||
Assert.NotNull(oAuthCard.TokenExchangeResource);
|
||||
})
|
||||
.StartTestAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OAuthPromptEndOnInvalidMessageSetting()
|
||||
{
|
||||
|
@ -788,7 +846,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
|
|||
var turnContext = new TurnContext(adapter, activity);
|
||||
|
||||
var userToken = await prompt.GetUserTokenAsync(turnContext, CancellationToken.None);
|
||||
|
||||
|
||||
Assert.Equal(Token, userToken.Token);
|
||||
}
|
||||
|
||||
|
@ -919,5 +977,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
|
|||
|
||||
return eventActivity;
|
||||
}
|
||||
|
||||
private class SignInResourceAdapter : TestAdapter
|
||||
{
|
||||
public override async Task<SignInResource> GetSignInResourceAsync(ITurnContext turnContext, AppCredentials oAuthAppCredentials, string connectionName, string userId, string finalRedirect = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = await base.GetSignInResourceAsync(turnContext, oAuthAppCredentials, connectionName, userId, finalRedirect, cancellationToken);
|
||||
result.TokenPostResource = new TokenPostResource()
|
||||
{
|
||||
SasUrl = $"https://www.fakesas.com/{connectionName}/{userId}"
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче