コード例 #1
0
        public void user_has_right_plan_wrong_option_value_should_redirect()
        {
            var reqPlanId   = 1;
            var optionName  = "HasThis";
            var optionValue = "Yes";
            var testUser    = new AppUser(new AspNetUser()
            {
                Id                 = Guid.NewGuid().ToString(),
                BillingOn          = DateTime.Now,
                MyShopifyDomain    = "store1.myshopify.com",
                ShopifyChargeId    = 1,
                Email              = "*****@*****.**",
                PlanId             = reqPlanId,
                UserName           = "******",
                ShopifyAccessToken = "thetoken"
            }, false);

            //mock user caching
            var userCache = new Mock <IUserCaching>();

            userCache.Setup(x => x.GetLoggedOnUser(It.IsAny <bool>())).Returns(Task.FromResult(testUser));

            var plan = new PlanAppModel(new Plan()
            {
                Id = reqPlanId
            });
            var def = new PlanDefinitionAppModel(new PlanDefinition()
            {
                OptionName  = optionName,
                OptionValue = "wrong value",
                PlanId      = plan.Id
            });
            var planReader = new Mock <IPlansReader>();

            planReader.Setup(x => x[It.IsAny <int>()]).Returns(plan);
            planReader.Setup(x => x[It.IsAny <int>(), It.IsAny <string>()]).Returns(def);

            //requires plan id 1

            RequiresPlan obj     = new RequiresPlan(userCache.Object, planReader.Object, realSettingsReader, mockLogger.Object, reqPlanId, optionName, optionValue);
            var          authCtx = _GetMockAuthrizationContext();

            obj.OnAuthorization(authCtx);
            userCache.Verify(x => x.GetLoggedOnUser(It.IsAny <bool>()), Times.Exactly(1));
            planReader.VerifyAll();
            Assert.IsType <RedirectToRouteResult>(authCtx.Result);
            var route      = (RedirectToRouteResult)authCtx.Result;
            var controller = route.RouteValues["controller"];
            var action     = route.RouteValues["action"];

            Assert.Equal(realSettingsReader.GetAppDashboardControllerName(), controller);
            Assert.Equal(DASHBOARD_ACTIONS.PlanDoesNotAllow.ToString(), action);
        }
コード例 #2
0
        public void user_has_right_plan_and_option_should_pass()
        {
            var reqPlanId   = 1;
            var optionName  = "HasThis";
            var optionValue = "Yes";
            var testUser    = new AppUser(new AspNetUser()
            {
                Id                 = Guid.NewGuid().ToString(),
                BillingOn          = DateTime.Now,
                MyShopifyDomain    = "store1.myshopify.com",
                ShopifyChargeId    = 1,
                Email              = "*****@*****.**",
                PlanId             = reqPlanId,
                UserName           = "******",
                ShopifyAccessToken = "thetoken"
            }, false);

            //mock user caching
            var userCache = new Mock <IUserCaching>();

            userCache.Setup(x => x.GetLoggedOnUser(It.IsAny <bool>())).Returns(Task.FromResult(testUser));

            var plan = new PlanAppModel(new Plan()
            {
                Id = reqPlanId
            });
            var def = new PlanDefinitionAppModel(new PlanDefinition()
            {
                OptionName  = optionName,
                OptionValue = optionValue,
                PlanId      = plan.Id
            });
            var planReader = new Mock <IPlansReader>();

            planReader.Setup(x => x[It.IsAny <int>()]).Returns(plan);
            planReader.Setup(x => x[It.IsAny <int>(), It.IsAny <string>()]).Returns(def);

            //requires plan id 1

            RequiresPlan obj     = new RequiresPlan(userCache.Object, planReader.Object, realSettingsReader, mockLogger.Object, reqPlanId, optionName, optionValue);
            var          authCtx = _GetMockAuthrizationContext();

            obj.OnAuthorization(authCtx);
            userCache.Verify(x => x.GetLoggedOnUser(It.IsAny <bool>()), Times.Exactly(1));
            planReader.VerifyAll();
            Assert.Null(authCtx.Result);
        }
コード例 #3
0
        private PlanDefinitionAppModel _GetDefinition(PlanAppModel plan, string optionName)
        {
            PlanDefinitionAppModel ret = null;

            if (plan != null)
            {
                if (plan.Definitions.ContainsKey(optionName))
                {
                    Logger.LogInformation($"Found option '{optionName}' in plan '{plan.Name}'");
                    ret = plan.Definitions[optionName];
                }
                else
                {
                    Logger.LogInformation($"Could not find option '{optionName}' in plan '{plan.Name}'");
                }
            }

            return(ret);
        }
コード例 #4
0
        public virtual async Task <IActionResult> ChargeResult(string shop, long charge_id)
        {
            using (Logger.BeginScope(new { Shop = shop, ChargeId = charge_id }))
            {
                try
                {
                    Logger.LogInformation("Getting current user.");
                    var user = await UserDbServiceHelper.GetAppUserByIdAsync(UserDbService, UserInContextHelper.GetCurrentUserId(HttpContext));

                    Logger.LogInformation($"Found user. Id is '{user.Id}'");
                    //to detect if its an upgrade we need users previous plan id, 0 means no previous plan.
                    Logger.LogInformation($"Getting previous plan info, if any.");
                    var previousPlan = user.GetPlanId();
                    Logger.LogInformation($"Previous plan ID is set to '{previousPlan}'.");
                    PlanAppModel newPlan = null;
                    ShopifyRecurringChargeObject charge = null;

                    try
                    {
                        Logger.LogInformation($"Retriving recurring charge info (before activation). Access token '{user.ShopifyAccessToken}' and charge id '{charge_id}'.");
                        charge = await ShopifyAPI.GetRecurringChargeAsync(user.MyShopifyDomain, user.ShopifyAccessToken, charge_id);

                        Logger.LogInformation($"Successfully retrived recurring charge info (before activation).Id is '{charge.Id}'.Associated plan name '{charge.Name}' and price '{charge.Price}'.");
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, "Error retriving recurring charge info (before activation).");
                        WebMsg.AddTempDanger(this, "Could not retrive charge status by charge id via shopify api (before activation).");
                        return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                    }

                    newPlan = PlanReader[charge.Name];

                    if (newPlan != null)
                    {
                        Logger.LogInformation($"New plan ID is set to '{newPlan.Id}'.");
                        Logger.LogInformation($"Recurring charge status (before activation) is '{charge.Status}'.");
                        if (charge.Status == "accepted")
                        {
                            //Lets activate the charge
                            try
                            {
                                Logger.LogInformation("Trying to activate the recurring charge.");
                                await ShopifyAPI.ActivateRecurringChargeAsync(user.MyShopifyDomain, user.ShopifyAccessToken, charge_id);

                                Logger.LogInformation("Recurring charge activationon is done.");
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex, $"Recurring charge activation failed.Redirecting to '{SHOPIFY_ACTIONS.ChoosePlan.ToString()}' action.");
                                WebMsg.AddTempDanger(this, "Could not activate the recurring charge via shopify api.Please try again.");
                                return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                            }

                            //Lets check if we were sucessful activating the charge
                            try
                            {
                                Logger.LogInformation("Checking recurring charge status after activation.");
                                charge = await ShopifyAPI.GetRecurringChargeAsync(user.MyShopifyDomain, user.ShopifyAccessToken, charge_id);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex, "Error getting recurring charge status after activation.");
                                WebMsg.AddTempDanger(this, "Could not retrieve charge status by id via shopify api (after activation). Please try again or contact support");
                                return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                            }

                            Logger.LogInformation($"Recurring Charge Status after activation is '{charge.Status}'.");
                            //if we were succesful
                            if (charge.Status == "active")
                            {
                                Logger.LogInformation($"Saving user payment information. User id '{user.Id}', charge id '{charge_id}' , plan id '{newPlan.Id}' and billing on '{charge.BillingOn}'.");
                                var updateResult = UserDbServiceHelper.SetUsersChargeInfo(UserDbService, user.Id, charge_id, newPlan.Id, charge.BillingOn);
                                if (!updateResult)
                                {
                                    Logger.LogCritical($"Could not save user payment information.Redirecting to '{SHOPIFY_ACTIONS.ChoosePlan.ToString()}' action.");
                                    await Emailer.UserPaymentInfoCouldNotBeSavedAsync(user, charge_id, charge.Name);

                                    //this.LogCoreException(new CoreException(CoreErrorType.APP_COULD_NOT_SAVE_CHARGE_INFO, errMessage + $".Activated Charge Id {charge.Id}", user, shop));
                                    WebMsg.AddTempDanger(this, "Could not save your payment confirmation in our db.Please try again.");
                                    return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                                }
                                else
                                {
                                    Logger.LogInformation("Succesfully saved user payment information.");
                                    Logger.LogInformation("Refreshing user cache data now.");
                                    user = await UserCache.GetLoggedOnUser(true);

                                    Logger.LogInformation("Now detecting installation type.");
                                    if (previousPlan > 0 && previousPlan != newPlan.Id)//its an upgrade
                                    {
                                        Logger.LogInformation("Installation was an upgrade type for existing store. Redirecting to RedirectAfterSuccessfulUpgrade().");
                                        await UserChangedPlan(user, newPlan.Id);             //handle upgrade event

                                        return(RedirectAfterSuccessfulUpgrade(charge.Name)); //now redirect
                                    }
                                    else//new installation
                                    {
                                        Logger.LogInformation("Installation was for a new store.");
                                        Logger.LogInformation("Now handling post installation tasks by calling DoPostInstallationTasks().");
                                        await DoPostInstallationTasks(user);//handle new installation event

                                        Logger.LogInformation("Done handling post installation tasks. ");
                                        await SendEmailsOnSuccessfullInstallation(user);//send emails

                                        Logger.LogInformation($"Now processing all webhooks defined in the appsettings.json by calling ProcessWebHooksCreation().");
                                        await ProcessWebhooks(user);

                                        Logger.LogInformation("Done processing webhooks defined in appsettings.json.");
                                        Logger.LogInformation("Now redirecting after successfull sign in.");
                                        return(RedirectAfterSuccessfullLogin());//now redirect
                                    }
                                }
                            }
                            else /*if status is not active*/
                            {
                                Logger.LogCritical($"SHopify could not activate the recurring charge. Redirecting to '{SHOPIFY_ACTIONS.ChoosePlan.ToString()}' action.");
                                WebMsg.AddTempDanger(this, "Shopify did not activate the recurring payment this app requested. Please try again by choosing a plan.");
                                return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                            }
                        }
                        else if (charge.Status == "declined")
                        {
                            Logger.LogCritical("Recurring charge was declined (before activation).Probably user declined payment.");
                            Logger.LogInformation("Calling UserCancelledPayment() event.");
                            await UserCancelledPayment(user, newPlan.Id);

                            Logger.LogInformation("Done handling UserCancelledPayment() event.");
                            if (user.GetPlanId() <= 0)
                            {
                                Logger.LogWarning("Redirecting to RedirectAfterNewUserCancelledPayment() as payment cancelled.");
                                return(RedirectAfterNewUserCancelledPayment(user));
                            }
                            else
                            {
                                Logger.LogWarning("Redirecting to RedirectAfterPlanChangePaymentDeclined() as payment declined");
                                return(RedirectAfterPlanChangePaymentDeclined());
                            }
                        }
                        else
                        {
                            Logger.LogCritical($"Recurring charge was not accepted by shopify (before activation). Redirecting to '{SHOPIFY_ACTIONS.ChoosePlan.ToString()}' action.");
                            WebMsg.AddTempDanger(this, "Payment was not accepted by shopify. Please try again.");
                            return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));
                        }
                    }
                    else
                    {
                        Logger.LogCritical($"Recurring charge's plan is not found in the loaded db plan list.Redirecting to '{SHOPIFY_ACTIONS.ChoosePlan.ToString()}' action.");
                        WebMsg.AddTempDanger(this, "Could not retrieve plan information.Please try again.");
                        return(RedirectToAction(SHOPIFY_ACTIONS.ChoosePlan.ToString(), Settings.GetShopifyControllerName()));//let the user try again
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning("Error occurred while executing ChargeResult().");
                    LogGenericError(ex);
                    throw ex;
                }
            }
        }
コード例 #5
0
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            _Logger.LogInformation($"Started checking requirement {_Requirement.ToString()}");
            if (context.Result == null)
            {
                _Logger.LogInformation("Getting current user.");
                var user = _UserCache.GetLoggedOnUser().Result;
                if (user == null)
                {
                    _Logger.LogWarning("User must be logged on before checking subscription.Redirecting to login page.");
                    context.Result = new RedirectToActionResult(ACCOUNT_ACTIONS.Login.ToString(), _Settings.GetAccountControllerName(), new { });
                }
                else
                {
                    _Logger.LogInformation($"Current user is '{user.MyShopifyDomain}'");
                    if (user.PlanId.HasValue == false)
                    {
                        _Logger.LogError($"Current user '{user.MyShopifyDomain}' doesn't have any valid plan.Throwing error.");
                        throw new Exception("Your account is not associated with any valid plan.Contact Support.");
                    }
                    else
                    {
                        bool requirementMet = false;
                        if (_PlanReader[user.PlanId.Value] == null)
                        {
                            _Logger.LogError($"Current user '{user.MyShopifyDomain}'  plan id ='{user.PlanId.Value}' is not found in the loaded plans list.");
                            throw new Exception($"Current user '{user.MyShopifyDomain}' plan id ='{user.PlanId.Value}' is not found in the loaded plans list.");
                        }
                        else if (_PlanReader[user.PlanId.Value].IsDev)
                        {
                            _Logger.LogInformation("Plan requirement is waved because user has DEV plan.");
                            requirementMet = true;
                        }
                        else
                        {
                            if (user.PlanId.Value != _Requirement.PlanId)
                            {
                                _Logger.LogWarning($"User '{user.MyShopifyDomain}' doesn't have required plan id = '{_Requirement.PlanId}'.");
                            }
                            else
                            {
                                PlanAppModel userPlan = _PlanReader[user.PlanId.Value];
                                _Logger.LogInformation($"User '{user.MyShopifyDomain}' has plan id = '{userPlan.Id}' and name = '{userPlan.Name}'");

                                if (_Requirement.OptionName != null && _Requirement.ExpectedValue != null)
                                {
                                    if (_PlanReader[userPlan.Id, _Requirement.OptionName]?.OptionValue == _Requirement.ExpectedValue)
                                    {
                                        requirementMet = true;
                                        _Logger.LogInformation($"User '{user.MyShopifyDomain}' has valid plan '{userPlan.Name}' and valid value = '{_Requirement.ExpectedValue}' for option = '{_Requirement.OptionName}'.");
                                    }
                                    else
                                    {
                                        _Logger.LogWarning($"User '{user.MyShopifyDomain}' plan = '{userPlan.Name}' doesn't have expected value for option ='{_Requirement.OptionName}'.");
                                    }
                                }
                                else
                                {
                                    _Logger.LogInformation($" User '{user.MyShopifyDomain}' hsa required plan.");
                                    requirementMet = true;
                                }
                            }

                            var controller = context.RouteData.Values["controller"];
                            var action     = context.RouteData.Values["action"];
                            if (!requirementMet)
                            {
                                _Logger.LogWarning($"User '{user.MyShopifyDomain}' is denied to '{controller}/{action}' route. Redirecting to app dashboard.");
                                context.Result = new RedirectToRouteResult(
                                    new RouteValueDictionary()
                                {
                                    { "controller", _Settings.GetAppDashboardControllerName() },
                                    { "action", DASHBOARD_ACTIONS.PlanDoesNotAllow.ToString() }
                                });
                            }
                            else
                            {
                                _Logger.LogInformation($"Requirement met. User '{user.MyShopifyDomain}' is allowed to '{controller}/{action}' route.");
                            }
                        }
                    }
                }
            }
        }