Esempio n. 1
0
        /// <summary>
        /// This method mainly tries to generate access token, creates user record, creates uninstall web hook and finally
        /// sends to the page where user can choose plan.
        /// </summary>
        /// <param name="shop">The store (URL) that is trying to access app.</param>
        /// <param name="code">Authrization code generated and send from shopify that will be used to gnerate access code</param>
        /// <returns></returns>
        public virtual async Task <IActionResult> AuthResult(string shop, string code)
        {
            using (Logger.BeginScope(new { Shop = shop, Code = code }))
            {
                try
                {
                    Logger.LogInformation("Checking request authenticity.");
                    if (ShopifyAPI.IsAuthenticRequest(Request))
                    {
                        Logger.LogInformation("Request is authentic.");
                        Logger.LogInformation("Checking if shop is authorized.");
                        if (UserDbServiceHelper.ShopIsAuthorized(UserDbService, shop))
                        {
                            Logger.LogInformation("Shop is authrorized.Calling _ProceedWithShopExists.");
                            return(await _ProceedWithShopExists(shop));
                        }
                        else
                        {
                            string accessToken = "";
                            try
                            {
                                Logger.LogWarning("Shop is NOT authrorized.Requesting authentication (access) token via api.");
                                accessToken = await ShopifyAPI.Authorize(shop, code);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogCritical("Shopify did not authorize.No access code received.Throwing exception.");
                                throw new Exception("Shopify did not authorize.No access code received.", ex);
                            }
                            Logger.LogInformation($"Rceived access token '{accessToken}'");
                            Thread.Sleep(500);
                            /*Get shop object cause we need the shop email address*/
                            ShopifyShopObject shopObj = null;
                            try
                            {
                                Logger.LogInformation("Request shopify shop obj using access token.");
                                shopObj = await ShopifyAPI.GetShopAsync(shop, accessToken);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogCritical("Could not retrive shop info obj.");
                                throw new Exception("Could not retrive shop info obj.", ex);
                            }

                            Logger.LogInformation($"Received shop info obj. Shop '{shopObj.Domain}' and email '{shopObj.Email}'");

                            #region User Creation
                            //Generate password
                            Logger.LogInformation("Generating password using shop info obj.");
                            string password = PassGenerator.GetPassword(new PasswordGeneratorInfo(shopObj.MyShopifyDomain, shopObj.Email));
                            Logger.LogInformation($"Successfully generated a password '{password}'.");
                            /*Now create an account */
                            Logger.LogInformation("Creating user account using shop info and password.");
                            var userCreation = await UserManager.CreateAppUser(shopObj.MyShopifyDomain, shopObj.Email, accessToken, password);

                            #endregion

                            if (userCreation.Succeeded)
                            {
                                AppUser user = await UserDbServiceHelper.GetUserByShopDomain(UserDbService, shopObj.MyShopifyDomain);

                                Logger.LogInformation($"Successfully created user for the shop.User id '{user.Id}'");

                                #region Uninstall hook creation
                                //As soon as user is created , create the uninstall hook
                                string uninstallCallback = "";
                                try
                                {
                                    Logger.LogInformation("Trying to find app/uninstalled topic in the web hook definition list in the appsettings.json file.");
                                    List <WebHookDefinition> whDefList = AppSettings.BindObject <List <WebHookDefinition> >("WebHooks", Config);

                                    if (whDefList.Count > 0)
                                    {
                                        var def = whDefList.Where(x => x.Topic.ToLower() == "app/uninstalled").FirstOrDefault();
                                        if (def.Topic == string.Empty)
                                        {
                                            Logger.LogWarning("List of webhooks found in the appsettings file but no app/uninstalled topic found.");
                                            uninstallCallback = ShopifyUrlHelper.GetAppUninstallWebHookUrl(Settings, user.Id);
                                            Logger.LogInformation($"Using system default uninstall callback url {uninstallCallback}.");
                                        }
                                        else
                                        {
                                            Logger.LogInformation($"Found app/uninstalled topic call in the appsettings file.The callback url is {def.Callback}.");
                                            uninstallCallback = ShopifyUrlHelper.GetAppUninstallWebHookUrl(def.Callback, user.Id);
                                        }
                                    }
                                    else
                                    {
                                        Logger.LogInformation("No weebhooks are defined in the appsettings file.");
                                        uninstallCallback = ShopifyUrlHelper.GetAppUninstallWebHookUrl(Settings, user.Id);
                                        Logger.LogInformation($"Using system default uninstall callback url {uninstallCallback}.");
                                    }

                                    Logger.LogInformation($"Trying to create uninstall web hook with call back url {uninstallCallback}.");
                                    var hook = await ShopifyAPI.CreateWebhookAsync(user.MyShopifyDomain, accessToken, new ShopifyWebhookObject()
                                    {
                                        Address = uninstallCallback,
                                        Topic   = "app/uninstalled"
                                    });

                                    Logger.LogInformation($"Successfully created uninstall web hook. Hook id '{hook.Id.Value}'.");
                                }
                                catch (Exception ex)
                                {
                                    LogGenericError(ex);
                                    Logger.LogCritical($"Failed creating uninstall webhook for user id '{user.Id}.The call back url is {uninstallCallback}'.");
                                    Logger.LogInformation("Sending UninstallHookCreationFailedAsync email.");
                                    var response = await Emailer.UninstallHookCreationFailedAsync(user, shopObj.MyShopifyDomain);

                                    if (response)
                                    {
                                        Logger.LogInformation("Successfully sent UninstallHookCreationFailedAsync email.");
                                    }
                                    else
                                    {
                                        Logger.LogInformation("Could not send UninstallHookCreationFailedAsync email.");
                                    }
                                    //we dont thorw error here...just gracefully ignore it
                                }
                                #endregion

                                #region Sign in
                                //Now sign in
                                Logger.LogInformation($"Trying to sign in using username '{user.UserName}' and password '{password}'. User id '{user.Id}'");
                                var signInStatus = await SignInManager.PasswordSignInAsync(user.UserName, password, false, lockoutOnFailure : false);

                                if (signInStatus.Succeeded)
                                {
                                    Logger.LogInformation($"Successfully signed in. User id '{user.Id}'");
                                    UserCache.ClearLoggedOnUser();
                                    return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                                }
                                else
                                {
                                    Logger.LogCritical($"Signing in for  User id '{user.Id}' failed.");
                                    throw new Exception("Could not sign you in using app account.Sign in failed!");
                                }
                                #endregion
                            }
                            else
                            {
                                var reasons = $"Reasons: { string.Join(", ", userCreation.Errors) }";
                                Logger.LogCritical($"User creation failed.{reasons}");
                                throw new Exception($"Could not create app user.{reasons}.");
                            }
                        }
                    }
                    else
                    {
                        Logger.LogCritical("Request is not authentic. Throwing error.");
                        throw new Exception("Request is not authentic.");
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning("Error occurred while executing AuthResult().");
                    LogGenericError(ex);
                    throw ex;
                }
            }
        }