Пример #1
0
        public void TokenExchangeInvokeResponseInitsWithNoArgs()
        {
            var tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse();

            Assert.NotNull(tokenExchangeInvokeResponse);
            Assert.IsType <TokenExchangeInvokeResponse>(tokenExchangeInvokeResponse);
        }
Пример #2
0
        private async Task <bool> ExchangedTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            TokenResponse tokenExchangeResponse = null;
            var           tokenExchangeRequest  = ((JObject)turnContext.Activity.Value)?.ToObject <TokenExchangeInvokeRequest>();

            try
            {
                var userTokenClient = turnContext.TurnState.Get <UserTokenClient>();
                if (userTokenClient != null)
                {
                    tokenExchangeResponse = await userTokenClient.ExchangeTokenAsync(
                        turnContext.Activity.From.Id,
                        _oAuthConnectionName,
                        turnContext.Activity.ChannelId,
                        new TokenExchangeRequest { Token = tokenExchangeRequest.Token },
                        cancellationToken).ConfigureAwait(false);
                }
                else if (turnContext.Adapter is IExtendedUserTokenProvider adapter)
                {
                    tokenExchangeResponse = await adapter.ExchangeTokenAsync(
                        turnContext,
                        _oAuthConnectionName,
                        turnContext.Activity.From.Id,
                        new TokenExchangeRequest { Token = tokenExchangeRequest.Token },
                        cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    throw new NotSupportedException("Token Exchange is not supported by the current adapter.");
                }
            }
#pragma warning disable CA1031 // Do not catch general exception types (ignoring, see comment below)
            catch
#pragma warning restore CA1031 // Do not catch general exception types
            {
                // Ignore Exceptions
                // If token exchange failed for any reason, tokenExchangeResponse above stays null,
                // and hence we send back a failure invoke response to the caller.
            }

            if (string.IsNullOrEmpty(tokenExchangeResponse?.Token))
            {
                // The token could not be exchanged (which could be due to a consent requirement)
                // Notify the sender that PreconditionFailed so they can respond accordingly.

                var invokeResponse = new TokenExchangeInvokeResponse
                {
                    Id             = tokenExchangeRequest.Id,
                    ConnectionName = _oAuthConnectionName,
                    FailureDetail  = "The bot is unable to exchange token. Proceed with regular login.",
                };

                await SendInvokeResponseAsync(turnContext, invokeResponse, HttpStatusCode.PreconditionFailed, cancellationToken).ConfigureAwait(false);

                return(false);
            }

            return(true);
        }
        public override async Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default)
        {
            // If the token was successfully exchanged already, it should be cached in TurnState along with the TokenExchangeInvokeRequest
            TokenResponse cachedTokenResponse = dc.Context.TurnState.Get <TokenResponse>(nameof(TokenResponse));

            if (cachedTokenResponse != null)
            {
                var tokenExchangeRequest = dc.Context.TurnState.Get <TokenExchangeInvokeRequest>(nameof(TokenExchangeInvokeRequest));
                if (tokenExchangeRequest == null)
                {
                    throw new InvalidOperationException("TokenResponse is present in TurnState, but TokenExchangeInvokeRequest is missing.");
                }

                var result = new PromptRecognizerResult <TokenResponse>();

                var exchangeResponse = new TokenExchangeInvokeResponse
                {
                    Id             = tokenExchangeRequest.Id,
                    ConnectionName = _settings.ConnectionName,
                };

                await dc.Context.SendActivityAsync(
                    new Activity
                {
                    Type  = ActivityTypesEx.InvokeResponse,
                    Value = new InvokeResponse
                    {
                        Status = (int)HttpStatusCode.OK,
                        Body   = exchangeResponse,
                    },
                }, cancellationToken).ConfigureAwait(false);

                result.Succeeded = true;
                result.Value     = new TokenResponse
                {
                    ChannelId      = cachedTokenResponse.ChannelId,
                    ConnectionName = cachedTokenResponse.ConnectionName,
                    Token          = cachedTokenResponse.Token,
                };

                return(await dc.EndDialogAsync(result.Value, cancellationToken).ConfigureAwait(false));
            }

            return(await base.ContinueDialogAsync(dc, cancellationToken).ConfigureAwait(false));
        }
Пример #4
0
        public void TokenExchangeInvokeResponseInits()
        {
            var id             = "id";
            var connectionName = "connectionName";
            var failureDetail  = "failureDetail";
            var properties     = new JObject();

            var tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse()
            {
                Id             = id,
                ConnectionName = connectionName,
                FailureDetail  = failureDetail,
                Properties     = properties,
            };

            Assert.NotNull(tokenExchangeInvokeResponse);
            Assert.IsType <TokenExchangeInvokeResponse>(tokenExchangeInvokeResponse);
            Assert.Equal(id, tokenExchangeInvokeResponse.Id);
            Assert.Equal(connectionName, tokenExchangeInvokeResponse.ConnectionName);
            Assert.Equal(failureDetail, tokenExchangeInvokeResponse.FailureDetail);
            Assert.Equal(properties, tokenExchangeInvokeResponse.Properties);
        }
        private static async Task <TokenResponse> OnContinueTokenExchangeAsync(UserTokenClient userTokenClient, string connectionName, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var tokenExchangeInvokeRequest = ((JObject)turnContext.Activity.Value)?.ToObject <TokenExchangeInvokeRequest>();

            HttpStatusCode httpStatusCode;
            TokenExchangeInvokeResponse tokenExchangeInvokeResponse;
            TokenResponse tokenResponse;

            if (tokenExchangeInvokeRequest == null)
            {
                httpStatusCode = HttpStatusCode.BadRequest;
                tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse
                {
                    ConnectionName = connectionName,
                    FailureDetail  = "The bot received an InvokeActivity that is missing a TokenExchangeInvokeRequest value. This is required to be sent with the InvokeActivity.",
                };
                tokenResponse = null;
            }
            else if (tokenExchangeInvokeRequest.ConnectionName != connectionName)
            {
                httpStatusCode = HttpStatusCode.BadRequest;
                tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse
                {
                    Id             = tokenExchangeInvokeRequest.Id,
                    ConnectionName = connectionName,
                    FailureDetail  = $"The bot received an InvokeActivity with a TokenExchangeInvokeRequest containing a ConnectionName {tokenExchangeInvokeRequest.ConnectionName} that does not match the ConnectionName {connectionName} expected by the bot's active OAuthPrompt. Ensure these names match when sending the InvokeActivityInvalid ConnectionName in the TokenExchangeInvokeRequest",
                };
                tokenResponse = null;
            }
            else
            {
                // inbound invoke activity appears valid so we will call the user token service

                var userId                = turnContext.Activity.From.Id;
                var channelId             = turnContext.Activity.ChannelId;
                var tokenExchangeResponse = await userTokenClient.ExchangeTokenAsync(userId, connectionName, channelId, new TokenExchangeRequest { Token = tokenExchangeInvokeRequest.Token }, cancellationToken).ConfigureAwait(false);

                if (tokenExchangeResponse == null || string.IsNullOrEmpty(tokenExchangeResponse.Token))
                {
                    httpStatusCode = HttpStatusCode.PreconditionFailed;
                    tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse
                    {
                        Id             = tokenExchangeInvokeRequest.Id,
                        ConnectionName = connectionName,
                        FailureDetail  = "The bot is unable to exchange token. Proceed with regular login.",
                    };
                    tokenResponse = null;
                }
                else
                {
                    httpStatusCode = HttpStatusCode.OK;
                    tokenExchangeInvokeResponse = new TokenExchangeInvokeResponse
                    {
                        Id             = tokenExchangeInvokeRequest.Id,
                        ConnectionName = connectionName,
                    };
                    tokenResponse = new TokenResponse
                    {
                        ChannelId      = tokenExchangeResponse.ChannelId,
                        ConnectionName = tokenExchangeResponse.ConnectionName,
                        Token          = tokenExchangeResponse.Token,
                    };
                }
            }

            await turnContext.SendActivityAsync(CreateInvokeResponseActivity(httpStatusCode, tokenExchangeInvokeResponse)).ConfigureAwait(false);

            return(tokenResponse);
        }