/// <summary> /// Initializes a new instance of the <see cref="OAuthPrompt"/> class. /// </summary> /// <param name="dialogId">The ID to assign to this prompt.</param> /// <param name="settings">Additional OAuth settings to use with this instance of the prompt.</param> /// <param name="validator">Optional, a <see cref="PromptValidator{FoundChoice}"/> that contains additional, /// custom validation for this prompt.</param> /// <remarks>The value of <paramref name="dialogId"/> must be unique within the /// <see cref="DialogSet"/> or <see cref="ComponentDialog"/> to which the prompt is added.</remarks> public OAuthPrompt(string dialogId, OAuthPromptSettings settings, PromptValidator <TokenResponse> validator = null) : base(dialogId) { if (string.IsNullOrWhiteSpace(dialogId)) { throw new ArgumentNullException(nameof(dialogId)); } _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _validator = validator; }
public static async Task SignOutUserAsync(ITurnContext turnContext, OAuthPromptSettings settings, CancellationToken cancellationToken) { var userTokenClient = turnContext.TurnState.Get <UserTokenClient>(); if (userTokenClient != null) { await userTokenClient.SignOutUserAsync(turnContext.Activity.From.Id, settings.ConnectionName, turnContext.Activity.ChannelId, cancellationToken).ConfigureAwait(false); } else if (turnContext.Adapter is IExtendedUserTokenProvider adapter) { await adapter.SignOutUserAsync(turnContext, settings.OAuthAppCredentials, settings.ConnectionName, turnContext.Activity?.From?.Id, cancellationToken).ConfigureAwait(false); } else { throw new NotSupportedException("OAuth prompt is not supported by the current adapter"); } }
/// <summary> /// Shared implementation of the SendOAuthCardAsync function. This is intended for internal use, to /// consolidate the implementation of the OAuthPrompt and OAuthInput. Application logic should use /// those dialog classes. /// </summary> /// <param name="settings">OAuthSettings.</param> /// <param name="turnContext">ITurnContext.</param> /// <param name="prompt">IMessageActivity.</param> /// <param name="cancellationToken">CancellationToken.</param> /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns> public static async Task SendOAuthCardAsync(OAuthPromptSettings settings, ITurnContext turnContext, IMessageActivity prompt, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); // Ensure prompt initialized prompt ??= Activity.CreateMessageActivity(); if (prompt.Attachments == null) { prompt.Attachments = new List <Attachment>(); } // Append appropriate card if missing if (!ChannelSupportsOAuthCard(turnContext.Activity.ChannelId)) { if (!prompt.Attachments.Any(a => a.Content is SigninCard)) { var signInResource = await UserTokenAccess.GetSignInResourceAsync(turnContext, settings, cancellationToken).ConfigureAwait(false); prompt.Attachments.Add(new Attachment { ContentType = SigninCard.ContentType, Content = new SigninCard { Text = settings.Text, Buttons = new[] { new CardAction { Title = settings.Title, Value = signInResource.SignInLink, Type = ActionTypes.Signin, }, }, }, }); } } else if (!prompt.Attachments.Any(a => a.Content is OAuthCard)) { var cardActionType = ActionTypes.Signin; var signInResource = await UserTokenAccess.GetSignInResourceAsync(turnContext, settings, cancellationToken).ConfigureAwait(false); var value = signInResource.SignInLink; // use the SignInLink when // in speech channel or // bot is a skill or // an extra OAuthAppCredentials is being passed in if (turnContext.Activity.IsFromStreamingConnection() || (turnContext.TurnState.Get <ClaimsIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity botIdentity && SkillValidation.IsSkillClaim(botIdentity.Claims)) || settings.OAuthAppCredentials != null) { if (turnContext.Activity.ChannelId == Channels.Emulator) { cardActionType = ActionTypes.OpenUrl; } } else if ((settings.ShowSignInLink != null && settings.ShowSignInLink == false) || (settings.ShowSignInLink == null && !ChannelRequiresSignInLink(turnContext.Activity.ChannelId))) { value = null; } prompt.Attachments.Add(new Attachment { ContentType = OAuthCard.ContentType, Content = new OAuthCard { Text = settings.Text, ConnectionName = settings.ConnectionName, Buttons = new[] { new CardAction { Title = settings.Title, Text = settings.Text, Type = cardActionType, Value = value }, }, TokenExchangeResource = signInResource.TokenExchangeResource, }, }); }
public OAuthPromptInternal(OAuthPromptSettings settings, PromptValidator <TokenResult> validator = null) { _settings = settings ?? throw new ArgumentException(nameof(settings)); _promptValidator = validator; }
/// <summary> /// Initializes a new instance of the <see cref="CloudOAuthPrompt"/> class. /// </summary> /// <param name="settings">Additional OAuth settings to use with this instance of the prompt.</param> /// <param name="validator">A custom validator that can be used against Message activities.</param> public CloudOAuthPrompt(OAuthPromptSettings settings, PromptValidator <TokenResponse> validator = null) { _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _validator = validator; }
public static async Task <TokenResponse> ExchangeTokenAsync(ITurnContext turnContext, OAuthPromptSettings settings, TokenExchangeRequest tokenExchangeRequest, CancellationToken cancellationToken) { var userTokenClient = turnContext.TurnState.Get <UserTokenClient>(); if (userTokenClient != null) { var userId = turnContext.Activity.From.Id; var channelId = turnContext.Activity.ChannelId; return(await userTokenClient.ExchangeTokenAsync(userId, settings.ConnectionName, channelId, tokenExchangeRequest, cancellationToken).ConfigureAwait(false)); } else if (turnContext.Adapter is IExtendedUserTokenProvider adapter) { return(await adapter.ExchangeTokenAsync(turnContext, settings.ConnectionName, turnContext.Activity.From.Id, tokenExchangeRequest, cancellationToken).ConfigureAwait(false)); } else { throw new NotSupportedException("OAuth prompt is not supported by the current adapter"); } }
/// <summary> /// Helper function used in BeginDialog. /// </summary> /// <param name="userTokenClient">The userTokenClient.</param> /// <param name="settings">The oauth settings.</param> /// <param name="turnContext">The turncontext.</param> /// <param name="prompt">A message activity for the prompt.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A Task.</returns> public static async Task SendOAuthCardAsync(UserTokenClient userTokenClient, OAuthPromptSettings settings, ITurnContext turnContext, IMessageActivity prompt, CancellationToken cancellationToken) { // Ensure prompt initialized prompt ??= Activity.CreateMessageActivity(); if (prompt.Attachments == null) { prompt.Attachments = new List <Attachment>(); } // Append appropriate card if missing if (!ChannelSupportsOAuthCard(turnContext.Activity.ChannelId)) { if (!prompt.Attachments.Any(a => a.Content is SigninCard)) { var signInResource = await userTokenClient.GetSignInResourceAsync(settings.ConnectionName, turnContext.Activity, null, cancellationToken).ConfigureAwait(false); prompt.Attachments.Add(new Attachment { ContentType = SigninCard.ContentType, Content = new SigninCard { Text = settings.Text, Buttons = new[] { new CardAction { Title = settings.Title, Value = signInResource.SignInLink, Type = ActionTypes.Signin, }, }, }, }); } } else if (!prompt.Attachments.Any(a => a.Content is OAuthCard)) { var cardActionType = ActionTypes.Signin; var signInResource = await userTokenClient.GetSignInResourceAsync(settings.ConnectionName, turnContext.Activity, null, cancellationToken).ConfigureAwait(false); var value = signInResource.SignInLink; // use the SignInLink when // in speech channel or // bot is a skill or // TODO: the OauthPrompt code also checked for || settings.OAuthAppCredentials != null if (turnContext.Activity.IsFromStreamingConnection() || IsSkill(turnContext.TurnState.Get <ClaimsIdentity>(BotAdapter.BotIdentityKey))) { if (turnContext.Activity.ChannelId == Channels.Emulator) { cardActionType = ActionTypes.OpenUrl; } } else if (!ChannelRequiresSignInLink(turnContext.Activity.ChannelId)) { value = null; } prompt.Attachments.Add(new Attachment { ContentType = OAuthCard.ContentType, Content = new OAuthCard { Text = settings.Text, ConnectionName = settings.ConnectionName, Buttons = new[] { new CardAction { Title = settings.Title, Text = settings.Text, Type = cardActionType, Value = value }, }, TokenExchangeResource = signInResource.TokenExchangeResource, }, }); } // Add the login timeout specified in OAuthPromptSettings to TurnState so it can be referenced if polling is needed if (!turnContext.TurnState.ContainsKey(TurnStateConstants.OAuthLoginTimeoutKey) && settings.Timeout.HasValue) { turnContext.TurnState.Add <object>(TurnStateConstants.OAuthLoginTimeoutKey, TimeSpan.FromMilliseconds(settings.Timeout.Value)); } // Set input hint if (string.IsNullOrEmpty(prompt.InputHint)) { prompt.InputHint = InputHints.AcceptingInput; } await turnContext.SendActivityAsync(prompt, cancellationToken).ConfigureAwait(false); }