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

Port To Asp .Net Core 2.0? #43

Open
GeraltTheWolf opened this issue Jan 15, 2018 · 1 comment
Open

Port To Asp .Net Core 2.0? #43

GeraltTheWolf opened this issue Jan 15, 2018 · 1 comment

Comments

@GeraltTheWolf
Copy link

GeraltTheWolf commented Jan 15, 2018

When will this be available to ASP Net Core 2.0?
To get it working on ASP .NET Core 2.0 I've made a copy of Callbak controller with a few changes.
Changes I've made are HttpResponseMessage changed to IActionResult , modified routing to Microsoft.AspNetCore.Mvc.Route.
Then I used Dependecy Injection to get MicrosoftAppCredentials and created new ConnectorClient
ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
insted of using this await Conversation.ResumeAsync(conversationRef, message);, and returned
new ContentResult(); Example:

[Microsoft.AspNetCore.Mvc.Route("[controller]")]
    public class CallbackController : Controller
    {
        private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
        private static readonly uint MaxWriteAttempts = 5;
        private readonly MicrosoftAppCredentials credentials;

        public CallbackController(MicrosoftAppCredentials credentials)
        {
            this.credentials = credentials;
        }

        [Microsoft.AspNetCore.Mvc.HttpGet]
        public async Task<IActionResult> Callback([FromQuery] string code, [FromQuery] string state, CancellationToken cancellationToken)
        {
            try
            {
                // Use the state parameter to get correct IAuthProvider and ResumptionCookie
                var decoded = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(state));
                var queryString = HttpUtility.ParseQueryString(decoded);
                var assembly = Assembly.Load(queryString["providerassembly"]);
                var type = assembly.GetType(queryString["providertype"]);
                var providername = queryString["providername"];
                IAuthProvider authProvider;
                if (type.GetConstructor(new Type[] { typeof(string) }) != null)
                    authProvider = (IAuthProvider)Activator.CreateInstance(type, providername);
                else
                    authProvider = (IAuthProvider)Activator.CreateInstance(type);

                var conversationRef = UrlToken.Decode<ConversationReference>(queryString["conversationRef"]);

                Activity message = conversationRef.GetPostToBotMessage();
                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    // Get the UserData from the original conversation
                    IBotDataStore<BotData> stateStore = scope.Resolve<IBotDataStore<BotData>>();
                    var key = Address.FromActivity(message);
                    var userData = await stateStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);                   
                    // Get Access Token using authorization code
                    var authOptions = userData.GetProperty<AuthenticationOptions>($"{authProvider.Name}{ContextConstants.AuthOptions}");
                    var token = await authProvider.GetTokenByAuthCodeAsync(authOptions, code);

                    // Generate magic number and attempt to write to userdata
                    int magicNumber = GenerateRandomNumber();
                    bool writeSuccessful = false;
                    uint writeAttempts = 0;
                    while (!writeSuccessful && writeAttempts++ < MaxWriteAttempts)
                    {
                        try
                        {
                            userData.SetProperty($"{authProvider.Name}{ContextConstants.AuthResultKey}", token);
                            if (authOptions.UseMagicNumber)
                            {
                                userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberKey}", magicNumber);
                                userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberValidated}", "false");
                            }
                            await stateStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
                            await stateStore.FlushAsync(key, CancellationToken.None);
                            writeSuccessful = true;
                        }
                        catch (Exception)
                        {
                            writeSuccessful = false;
                        }
                    }
                    var resp = new ContentResult();
                    if (!writeSuccessful)
                    {
                        message.Text = String.Empty; // fail the login process if we can't write UserData
                     ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
                        await client.Conversations.SendToConversationAsync(message);
                        resp.ContentType = @"text/html";
                        resp.Content = "<html><body>Could not log you in at this time, please try again later</body></html>";
                    }
                    else
                    {
                        message.Text = String.Empty;
                        ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl), credentials);
                        await client.Conversations.SendToConversationAsync(message);
                        resp.ContentType = @"text/html";
                        resp.Content = $"<html><body>Almost done! Please copy this number and paste it back to your chat so your authentication can complete:<br/> <h1>{magicNumber}</h1>.</body></html>";

                    }
                    return resp;
                }
            }
            catch (Exception ex)
            {
                // Callback is called with no pending message as a result the login flow cannot be resumed.             
                return BadRequest();
            }
        }
        private int GenerateRandomNumber()
        {
            int number = 0;
            byte[] randomNumber = new byte[1];
            do
            {
                rngCsp.GetBytes(randomNumber);
                var digit = randomNumber[0] % 10;
                number = number * 10 + digit;
            } while (number.ToString().Length < 6);
            return number;
        }

    }
@stevensrf11
Copy link

Probably never.
You know Microsoft break it and forget about it

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants