public async Task ProcessChangePlanAsync( AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken = default) { var queryParams = new List <Tuple <string, string> > { new Tuple <string, string>( "subscriptionId", provisionModel.SubscriptionId.ToString()), new Tuple <string, string>("planId", provisionModel.NewPlanId) }; var emailText = $"<p>Updated subscription from {provisionModel.PlanId} to {provisionModel.NewPlanId}."; emailText += "Please take the required action, then return to this email and click the following link to confirm. "; emailText += $"{this.BuildALink("Update", queryParams, "Click here to update subscription")}.</p>"; emailText += $"<div> <p> Details are</p> <div> {this.BuildTable(JObject.Parse(JsonConvert.SerializeObject(provisionModel)))}</div></div>"; await this.SendEmailAsync( () => $"Update subscription, {provisionModel.SubscriptionName}", () => emailText, cancellationToken); }
// GET: LandingPage public async Task <ActionResult> Index(string token) { if (string.IsNullOrEmpty(token)) { this.ModelState.AddModelError(string.Empty, "Token URL parameter cannot be empty"); return(this.View()); } var resolvedSubscription = await this.fulfillmentManager.ResolveSubscriptionAsync(token); if (resolvedSubscription == default(MarketplaceSubscription)) { this.ModelState.AddModelError(string.Empty, "Cannot resolve subscription"); return(this.View()); } var fullName = (this.User.Identity as ClaimsIdentity)?.FindFirst("name")?.Value; var emailAddress = this.User.Identity.GetUserEmail(); var provisioningModel = new AzureSubscriptionProvisionModel { FullName = fullName, PlanName = resolvedSubscription.PlanId, SubscriptionId = resolvedSubscription.SubscriptionId, Email = emailAddress, OfferId = resolvedSubscription.OfferId, SubscriptionName = resolvedSubscription.SubscriptionName, Region = TargetContosoRegionEnum.NorthAmerica, MaximumNumberOfThingsToHandle = 0 }; return(this.View(provisioningModel)); }
public void BuildCustomDataTable() { var item = new AzureSubscriptionProvisionModel() { Location = FactionLocation.SantaClaraCA, PlanId = "test plan", SubscriptionId = Guid.NewGuid(), PurchaserTenantId = Guid.NewGuid(), CustomBundleOptions = new FactionCustomBundleModel() { RequestedPerformanceTier = FactionCustomPerformanceTier.Archive, RequestedBandwidth = "10 Gbps", RequestedStorageSize = "500 TB" }, TechnicalContactEmail = "*****@*****.**", TechnicalContactName = "Technical Contact", TechnicalContactPhone = "123-456-780", }; item.TechnicalDetails.RequestedShareName = "Share1"; item.TechnicalDetails.SupportCIFS = true; item.TechnicalDetails.SupportNFS = true; var tableString = CommandCenterEMailHelper.BuildTable(item); Assert.IsTrue(tableString.Length > 10); }
/// <inheritdoc/> public async Task ProcessNewSubscriptionAsyc( AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken = default) { if (provisionModel == null) { throw new ArgumentNullException(nameof(provisionModel)); } var queryParams = new List <Tuple <string, string> > { new Tuple <string, string>( "subscriptionId", provisionModel.SubscriptionId.ToString()), new Tuple <string, string>("planId", provisionModel.PlanId), }; var emailText = "<p>New subscription. Please take the required action, then return to this email and click the following link to confirm. "; emailText += $"{this.BuildALink("Activate", queryParams, "Click here to activate subscription")}.</p>"; emailText += $"<div> <p> Details are</p> <div> {BuildTable(JObject.Parse(JsonConvert.SerializeObject(provisionModel)))}</div></div>"; await this.SendEmailAsync( () => $"New subscription, {provisionModel.SubscriptionName}", () => emailText, cancellationToken).ConfigureAwait(false); }
public async Task <ActionResult> Index(AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken) { if (provisionModel == null) { throw new ArgumentNullException(nameof(provisionModel)); } var urlBase = $"{this.Request.Scheme}://{this.Request.Host}"; this.options.BaseUrl = new Uri(urlBase); try { // A new subscription will have PendingFulfillmentStart as status if (provisionModel.SubscriptionStatus == SubscriptionStatusEnum.PendingFulfillmentStart) { await this.notificationHandler.ProcessNewSubscriptionAsyc(provisionModel, cancellationToken); } else { await this.notificationHandler.ProcessChangePlanAsync(provisionModel, cancellationToken); } return(this.RedirectToAction(nameof(this.Success))); } catch (Exception ex) { return(this.BadRequest(ex)); } }
/// <inheritdoc/> public async Task <bool> InsertRequestAsync(AzureSubscriptionProvisionModel modelToInsert) { // Return False if we cannot connect to the Cosmos instance. if (!await this.CreateResourcesAsync()) { return(false); } // Model to Insert does not contain a valid subscription Id if (modelToInsert.SubscriptionId == Guid.Empty) { return(false); } // Return True if an instance has already been persisted for this subscription. if (await this.GetRequestBySubscriptionIdAsync(modelToInsert.SubscriptionId) != null) { return(true); } try { await this.cosmosRequestContainer.CreateItemAsync(modelToInsert); } catch (CosmosException ce) { this.logger.LogError($"Error Creating Request Document. Subscription ID: {modelToInsert.SubscriptionId}. Message: {ce.Message}"); return(false); } return(false); }
/// <inheritdoc/> public async Task ProcessChangePlanAsync(AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken = default) { if (provisionModel == null) { throw new ArgumentNullException(nameof(provisionModel)); } await this.SendLandingPageMessageAsync(provisionModel, MailLinkControllerName, "Update", cancellationToken); }
/// <inheritdoc/> public async Task ProcessNewSubscriptionAsyc(AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken = default) { if (provisionModel == null) { throw new ArgumentNullException(nameof(provisionModel)); } await this.SendLandingPageMessageAsync(provisionModel, MailLinkControllerName, "Activate", cancellationToken).ConfigureAwait(false); }
public void GetPropertyDisplayName() { var item = new AzureSubscriptionProvisionModel() { Location = FactionLocation.SantaClaraCA }; var displayName1 = item.GetDisplayName(nameof(item.Location)); var displayName2 = item.GetDisplayName(nameof(item.TechnicalContactEmail)); Assert.AreEqual("Location", displayName1); Assert.AreEqual("Technical contact email", displayName2); }
public async Task <ActionResult> Index(AzureSubscriptionProvisionModel provisionModel) { var urlBase = $"{this.Request.Scheme}://{this.Request.Host}"; this.options.BaseUrl = urlBase; try { await this.notificationHelper.ProcessActivateAsync(provisionModel); return(this.RedirectToAction(nameof(this.Success))); } catch (Exception ex) { return(this.View(ex)); } }
public async Task ProcessStartProvisioningAsync(AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken = default) { var queryParams = new List <Tuple <string, string> > { new Tuple <string, string>( "subscriptionId", provisionModel.SubscriptionId.ToString()), new Tuple <string, string>("planId", provisionModel.PlanName) }; await this.SendEmailAsync( () => $"New subscription, {provisionModel.SubscriptionName}", () => $"<p>New subscription. Please take the required action, then return to this email and click the following link to confirm. {this.BuildALink("Update", queryParams, "Click here to activate subscription")}.</p>" + $"<div> <p> Details are</p> <div> {BuildTable(JObject.Parse(JsonConvert.SerializeObject(provisionModel))) }</div></div>", cancellationToken); }
/// <summary> /// Builds an HTML table of the options entered by the user when building a new subscription. /// </summary> /// <param name="model">The data model associated with this provisioning request.</param> /// <returns>An HTML table definition in string format.</returns> public static string BuildTable(AzureSubscriptionProvisionModel model) { var returnString = $"<table border=\"1\" align=\"left\">"; if (model != null) { returnString += BuildRow(model.GetDisplayName(nameof(model.Location)), model.Location.GetDisplayName()); returnString += BuildRow(model.GetDisplayName(nameof(model.PlanId)), model?.PlanId); if (model.CustomBundleOptions != null) { var cbo = model.CustomBundleOptions; returnString += BuildRow(cbo.GetDisplayName(nameof(cbo.RequestedPerformanceTier)), cbo.RequestedPerformanceTier.GetDisplayName()); returnString += BuildRow(cbo.GetDisplayName(nameof(cbo.RequestedBandwidth)), cbo?.RequestedBandwidth); returnString += BuildRow(cbo.GetDisplayName(nameof(cbo.RequestedStorageSize)), cbo?.RequestedStorageSize); } returnString += BuildRow(model.GetDisplayName(nameof(model.FullName)), model.FullName); returnString += BuildRow(model.GetDisplayName(nameof(model.BusinessUnitContactEmail)), model.BusinessUnitContactEmail); returnString += BuildRow(model.GetDisplayName(nameof(model.PurchaserEmail)), model.PurchaserEmail); returnString += BuildRow(model.GetDisplayName(nameof(model.TechnicalContactName)), model?.TechnicalContactName); returnString += BuildRow(model.GetDisplayName(nameof(model.TechnicalContactEmail)), model?.TechnicalContactEmail); returnString += BuildRow(model.GetDisplayName(nameof(model.TechnicalContactPhone)), model?.TechnicalContactPhone); if (model.TechnicalDetails != null) { var techDetails = model.TechnicalDetails; returnString += "<tr><th align=\"center\">Technical Details></th><th></th></tr>"; returnString += BuildRow(techDetails.GetDisplayName(nameof(techDetails.RequestedShareName)), techDetails?.RequestedShareName); returnString += BuildRow(techDetails.GetDisplayName(nameof(techDetails.SupportNFS)), techDetails.SupportNFS ? "Yes" : "No"); returnString += BuildRow(techDetails.GetDisplayName(nameof(techDetails.SupportCIFS)), techDetails.SupportCIFS ? "Yes" : "No"); returnString += BuildRow(techDetails.GetDisplayName(nameof(techDetails.RequestedSubnet)), techDetails?.RequestedSubnet); } returnString += "<tr><th align=\"center\">Azure Details></th><th></th></tr>"; returnString += BuildRow(model.GetDisplayName(nameof(model.OfferId)), model?.OfferId); returnString += BuildRow(model.GetDisplayName(nameof(model.PurchaserTenantId)), model.PurchaserTenantId.ToString()); returnString += BuildRow(model.GetDisplayName(nameof(model.SubscriptionId)), model.SubscriptionId.ToString()); returnString += BuildRow(model.GetDisplayName(nameof(model.SubscriptionName)), model?.SubscriptionName ?? NotProvidedValue); returnString += BuildRow(model.GetDisplayName(nameof(model.ExistingSpendCommitments)), model.ExistingSpendCommitments ? "Yes" : "No"); returnString += $"</table>"; } return(returnString); }
public async Task <ActionResult> Index( AzureSubscriptionProvisionModel provisionModel, CancellationToken cancellationToken) { var urlBase = $"{this.Request.Scheme}://{this.Request.Host}"; this.options.BaseUrl = urlBase; try { this.fulfillmentHandler.ProcessLandingPageAsync(provisionModel, cancellationToken); return(this.RedirectToAction(nameof(this.Success))); } catch (Exception ex) { return(this.BadRequest(ex)); } }
private async Task SendLandingPageMessageAsync(AzureSubscriptionProvisionModel provisionModel, string controllerName, string actionName, CancellationToken cancellationToken) { if (provisionModel == null) { throw new ArgumentNullException(nameof(provisionModel)); } var queryParams = new List <Tuple <string, string> > { new Tuple <string, string>( "subscriptionId", provisionModel.SubscriptionId.ToString()), new Tuple <string, string>("planId", provisionModel.NewPlanId == null ? provisionModel.PlanId : provisionModel.NewPlanId), }; var message = $"{{\"ActionLink\": \"{this.BuildLink(queryParams, controllerName, actionName)}\", \"Payload\" : {JsonConvert.SerializeObject(provisionModel)} }}"; await this.queueClient.SendMessageAsync(message, cancellationToken).ConfigureAwait(false); }
public void BuildStandardDataTable() { var item = new AzureSubscriptionProvisionModel() { Location = FactionLocation.SantaClaraCA, PlanId = "test plan", SubscriptionId = Guid.NewGuid(), PurchaserTenantId = Guid.NewGuid(), TechnicalContactEmail = "*****@*****.**", TechnicalContactName = "Technical Contact", TechnicalContactPhone = "123-456-780", }; item.TechnicalDetails.RequestedShareName = "Share1"; item.TechnicalDetails.SupportCIFS = true; item.TechnicalDetails.SupportNFS = true; var tableString = CommandCenterEMailHelper.BuildTable(item); Assert.IsTrue(tableString.Length > 10); }
// GET: LandingPage public async Task <ActionResult> Index(string token) { this.logger.LogError($"Token {token}"); var resolvedSubscription = await this.fulfillmentManager.ResolveSubscriptionAsync(token); if (resolvedSubscription == default(MarketplaceSubscription)) { this.ModelState.AddModelError(string.Empty, "Cannot resolve subscription"); return(this.View()); } var sku = (await this.subscriptionManager.GetSkusAsync(SalesChannelEnum.Azure)) .FirstOrDefault(s => s.Name == resolvedSubscription.PlanId); if (sku == default(Sku)) { return(this.NotFound("A Sku with the plan name on the resolved subscription does not exist.")); } var fullName = (this.User.Identity as ClaimsIdentity)?.FindFirst("name")?.Value; var emailAddress = (this.User.Identity as ClaimsIdentity)?.FindFirst("preferred_username")?.Value; var provisioningModel = new AzureSubscriptionProvisionModel { FullName = fullName, PlanName = resolvedSubscription.PlanId, SubscriptionId = resolvedSubscription.SubscriptionId, Email = emailAddress, PlanId = sku.Id, OfferId = resolvedSubscription.OfferId, SubscriptionName = resolvedSubscription.SubscriptionName }; return(this.View(provisioningModel)); }
public async Task <ActionResult> Index(AzureSubscriptionProvisionModel provisionModel) { try { // First create the admin user on Contoso side var user = new IdentityUser { UserName = provisionModel.Email, Email = provisionModel.Email }; var result = await this.userManager.CreateAsync(user, provisionModel.Password); // Create the user and admin roles if they are not already in the store await this.roleManager.EnsureRolesExistAsync(); var roleResult = await this.userManager.AddToRoleAsync(user, Constants.CustomerAdminRoleName); // Better do this in a compensating transaction fashion, but this is a sample. // Implement a IDisposable transaction manager, register operations that be rolled back // as add, and roll back if fails in Dispose if (!await this.customerManager.CustomerUserExistsByUserNameAsync(provisionModel.Email)) { var addSubscriptionResult = await this.subscriptionManager.ProvisionSubscriptionWithAdminAsync( provisionModel.Email, provisionModel.CustomerRegion, provisionModel.FullName, provisionModel.PlanId.Value, provisionModel.SubscriptionId); foreach (var error in addSubscriptionResult.Errors) { this.ModelState.AddModelError(string.Empty, error.Description); } } var provisioningStatus = await this.provisioningManager.AddEnvironmentAsync( provisionModel.Email.GetDomainNameFromEmail(), provisionModel.PlanId.Value, Enum.GetName(typeof(CustomerRegionEnum), provisionModel.CustomerRegion)); if (provisioningStatus.Success) { var activationResult = await this.fulfillmentManager.ActivateSubscriptionAsync( provisionModel.SubscriptionId, provisionModel.PlanName, null); if (activationResult != default(MarketplaceSubscription)) { activationResult.OfferId = provisionModel.OfferId; activationResult.SubscriptionName = provisionModel.SubscriptionName; return(this.RedirectToAction(nameof(this.Success), activationResult)); } } return(this.RedirectToAction(nameof(Index))); } catch (Exception ex) { return(this.View(ex)); } }
public async Task <ActionResult> Index(string token, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(token)) { this.ModelState.AddModelError(string.Empty, "Token URL parameter cannot be empty"); this.ViewBag.Message = "Token URL parameter cannot be empty"; return(this.View()); } ResolvedSubscription resolvedSubscription = null; Microsoft.Marketplace.SaaS.Models.Subscription subscriptionDetails = null; Azure.Response <Microsoft.Marketplace.SaaS.Models.SubscriptionPlans> availablePlans = null; bool anyPendingOperations = false; if (token.ToLowerInvariant() != SampleToken) { // Get the subscription for the offer from the marketplace purchase identification token resolvedSubscription = await this.marketplaceProcessor.GetSubscriptionFromPurchaseIdentificationTokenAsync(token, cancellationToken); if (resolvedSubscription == default(ResolvedSubscription)) { this.ViewBag.Message = "Token did not resolve to a subscription"; return(this.View()); } subscriptionDetails = resolvedSubscription.Subscription; // Populate the available plans for this subscription from the API availablePlans = await this.marketplaceClient.Fulfillment.ListAvailablePlansAsync( resolvedSubscription.Id.Value, null, null, cancellationToken); // See if there are pending operations for this subscription var pendingOperations = await this.marketplaceClient.Operations.ListOperationsAsync( resolvedSubscription.Id.Value, null, null, cancellationToken); anyPendingOperations = pendingOperations?.Value.Operations?.Any(o => o.Status == OperationStatusEnum.InProgress) ?? false; } var graphApiUser = await this.graphServiceClient.Me.Request().GetAsync(); var isSampleToken = string.Equals(token, SampleToken, StringComparison.InvariantCultureIgnoreCase); var provisioningModel = new AzureSubscriptionProvisionModel { // Landing page is the only place to capture the customer's contact details // It can be present in multiple places: // - the details received from the Graph API // - beneficiary information on the subscription details // it is also possible that the Graph API NameFromOpenIdConnect = (this.User.Identity as ClaimsIdentity)?.FindFirst("name")?.Value, EmailFromClaims = this.User.Identity.GetUserEmail(), EmailFromGraph = graphApiUser.Mail ?? string.Empty, NameFromGraph = graphApiUser.DisplayName ?? string.Empty, UserPrincipalName = graphApiUser.UserPrincipalName ?? string.Empty, PurchaserEmail = graphApiUser.Mail ?? string.Empty, // Get the other potential contact information from the marketplace API PurchaserUPN = isSampleToken ? "*****@*****.**" : subscriptionDetails?.Purchaser?.EmailId, PurchaserTenantId = isSampleToken ? Guid.Empty : subscriptionDetails?.Purchaser?.TenantId ?? Guid.Empty, BeneficiaryUPN = isSampleToken ? "*****@*****.**" : subscriptionDetails?.Beneficiary?.EmailId, BeneficiaryTenantId = isSampleToken ? Guid.Empty : subscriptionDetails?.Beneficiary?.TenantId ?? Guid.Empty, // Maybe the end users are a completely different set of contacts, start with one BusinessUnitContactEmail = this.User.Identity.GetUserEmail(), PlanId = isSampleToken ? "*****@*****.**" : resolvedSubscription.PlanId, SubscriptionId = isSampleToken ? Guid.Empty : resolvedSubscription.Id.Value, OfferId = isSampleToken ? "sample offer" : resolvedSubscription.OfferId, SubscriptionName = isSampleToken ? "sample subscription" : resolvedSubscription.SubscriptionName, SubscriptionStatus = isSampleToken ? SubscriptionStatusEnum.PendingFulfillmentStart : subscriptionDetails?.SaasSubscriptionStatus ?? SubscriptionStatusEnum.NotStarted, Region = TargetContosoRegionEnum.NorthAmerica, AvailablePlans = isSampleToken ? new System.Collections.Generic.List <Plan>() : availablePlans?.Value.Plans.ToList(), PendingOperations = isSampleToken ? false : anyPendingOperations, }; return(this.View(provisioningModel)); }
/// <summary> /// Landing page get. /// </summary> /// <param name="token">Marketplace purchase identification token.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Action result.</returns> public async Task <ActionResult> Index(string token, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(token)) { this.ModelState.AddModelError(string.Empty, "Token URL parameter cannot be empty"); this.ViewBag.Message = "Token URL parameter cannot be empty"; return(this.View()); } // Get the subscription for the offer from the marketplace purchase identification token var resolvedSubscription = await this.marketplaceProcessor.GetSubscriptionFromPurchaseIdentificationTokenAsync(token, cancellationToken).ConfigureAwait(false); // Rest is implementation detail. In this sample, we chose allow the subscriber to change the plan for an activated subscriptio if (resolvedSubscription == default(ResolvedSubscription)) { this.ViewBag.Message = "Token did not resolve to a subscription"; return(this.View()); } // resolvedSubscription.Subscription is null when calling mock endpoint var existingSubscription = resolvedSubscription.Subscription; var availablePlans = await this.marketplaceClient.Fulfillment.ListAvailablePlansAsync( resolvedSubscription.Id.Value, null, null, cancellationToken).ConfigureAwait(false); var pendingOperations = await this.marketplaceClient.Operations.ListOperationsAsync( resolvedSubscription.Id.Value, null, null, cancellationToken).ConfigureAwait(false); var provisioningModel = new AzureSubscriptionProvisionModel { PlanId = resolvedSubscription.PlanId, SubscriptionId = resolvedSubscription.Id.Value, OfferId = resolvedSubscription.OfferId, SubscriptionName = resolvedSubscription.SubscriptionName, PurchaserEmail = existingSubscription?.Purchaser?.EmailId, PurchaserTenantId = existingSubscription?.Purchaser?.TenantId ?? Guid.Empty, // Assuming this will be set to the value the customer already set when subscribing, if we are here after the initial subscription activation // Landing page is used both for initial provisioning and configuration of the subscription. Region = TargetContosoRegionEnum.NorthAmerica, AvailablePlans = availablePlans?.Value.Plans.ToList(), SubscriptionStatus = existingSubscription?.SaasSubscriptionStatus ?? SubscriptionStatusEnum.NotStarted, PendingOperations = pendingOperations?.Value.Operations?.Any(o => o.Status == OperationStatusEnum.InProgress) ?? false, }; if (provisioningModel != default) { provisioningModel.FullName = (this.User.Identity as ClaimsIdentity)?.FindFirst("name")?.Value; provisioningModel.Email = this.User.Identity.GetUserEmail(); provisioningModel.BusinessUnitContactEmail = this.User.Identity.GetUserEmail(); return(this.View(provisioningModel)); } this.ModelState.AddModelError(string.Empty, "Cannot resolve subscription"); return(this.View()); }
/// <summary> /// Landing page get. /// </summary> /// <param name="token">Marketplace purchase identification token.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Action result.</returns> public async Task <ActionResult> Index(string token, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(token)) { this.ModelState.AddModelError(string.Empty, "Token URL parameter cannot be empty"); this.ViewBag.Message = "Token URL parameter cannot be empty"; return(this.View()); } // Get the subscription for the offer from the marketplace purchase identification token var resolvedSubscription = await this.marketplaceProcessor.GetSubscriptionFromPurchaseIdentificationTokenAsync(token, cancellationToken).ConfigureAwait(false); // Rest is implementation detail. In this sample, we chose allow the subscriber to change the plan for an activated subscriptio if (resolvedSubscription == default(ResolvedSubscription)) { this.ViewBag.Message = "Token did not resolve to a subscription"; return(this.View()); } // resolvedSubscription.Subscription is null when calling mock endpoint var existingSubscription = resolvedSubscription.Subscription; // var availablePlans = await this.marketplaceClient.Fulfillment.ListAvailablePlansAsync( // resolvedSubscription.Id.Value, // null, // null, // cancellationToken).ConfigureAwait(false); var existingRequest = await this.requestPersistenceStore.GetRequestBySubscriptionIdAsync(resolvedSubscription.Id.Value); if (existingRequest != null) { return(this.RedirectToAction(nameof(this.RequestSubmitted))); } var pendingOperations = await this.marketplaceClient.Operations.ListOperationsAsync( resolvedSubscription.Id.Value, null, null, cancellationToken).ConfigureAwait(false); var provisioningModel = new AzureSubscriptionProvisionModel { PlanId = resolvedSubscription.PlanId, SubscriptionId = resolvedSubscription.Id.Value, OfferId = resolvedSubscription.OfferId, SubscriptionName = resolvedSubscription.SubscriptionName, PurchaserEmail = existingSubscription?.Purchaser?.EmailId, PurchaserTenantId = existingSubscription?.Purchaser?.TenantId ?? Guid.Empty, // Assuming this will be set to the value the customer already set when subscribing, if we are here after the initial subscription activation // Landing page is used both for initial provisioning and configuration of the subscription. SubscriptionStatus = existingSubscription?.SaasSubscriptionStatus ?? SubscriptionStatusEnum.NotStarted, PendingOperations = pendingOperations?.Value.Operations?.Any(o => o.Status == OperationStatusEnum.InProgress) ?? false, }; if (provisioningModel != default) { provisioningModel.FullName = (this.User.Identity as ClaimsIdentity)?.FindFirst("name")?.Value; provisioningModel.Email = this.User.Identity.GetUserEmail(); provisioningModel.BusinessUnitContactEmail = this.User.Identity.GetUserEmail(); if (string.Equals(provisioningModel.PlanId, "custom_bundle", StringComparison.InvariantCultureIgnoreCase)) { provisioningModel.CustomBundleOptions = new FactionCustomBundleModel(); } else { provisioningModel.CustomBundleOptions = null; } this.TryValidateModel(provisioningModel); return(this.View(provisioningModel)); } this.ModelState.AddModelError(string.Empty, "Cannot resolve subscription"); return(this.View()); // This is just for testing or Demo purposes // var model = new AzureSubscriptionProvisionModel(); // model.CustomBundleOptions = new FactionCustomBundleModel(); // this.TryValidateModel(model); // return this.View(model); }