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); }
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); }
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); }
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; } } }
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."); } } } } } }