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);
        }
예제 #2
0
        // 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));
        }
예제 #3
0
        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));
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }
예제 #10
0
        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));
            }
        }
예제 #11
0
        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);
        }
예제 #13
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        // 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));
        }
예제 #17
0
        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));
        }
예제 #19
0
        /// <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());
        }
예제 #20
0
        /// <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);
        }