internal static MarketplaceSubscription From(ResolvedSubscription subscription, StatusEnum newState)
 {
     return(new MarketplaceSubscription
     {
         SubscriptionId = subscription.SubscriptionId,
         OfferId = subscription.OfferId,
         PlanId = subscription.PlanId,
         Quantity = subscription.Quantity,
         SubscriptionName = subscription.SubscriptionName,
         State = newState
     });
 }
        public async Task <Response <ResolvedSubscription> > ResolveAsync(string xMsMarketplaceToken, Guid?requestId = null, Guid?correlationId = null, CancellationToken cancellationToken = default)
        {
            if (xMsMarketplaceToken == null)
            {
                throw new ArgumentNullException(nameof(xMsMarketplaceToken));
            }

            using var message = CreateResolveRequest(xMsMarketplaceToken, requestId, correlationId);
            await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false);

            switch (message.Response.Status)
            {
            case 200:
            {
                ResolvedSubscription value = default;
                using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false);

                value = ResolvedSubscription.DeserializeResolvedSubscription(document.RootElement);
                return(Response.FromValue(value, message.Response));
            }
Ejemplo n.º 3
0
        public IActionResult App(AppViewModel model)
        {
            var resolvedSubscription = new ResolvedSubscription()
            {
                SubscriptionId   = Guid.NewGuid(),
                SubscriptionName = $"{model.AppOffer.Name} subscription",
                OfferId          = model.AppOffer.OfferID,
                PlanId           = model.Plan.PlanId,
                Quantity         = model.Quantity,
                TenantId         = Guid.Parse(User.GetTenantId())
            };

            // save data in cache
            _cache.Set(resolvedSubscription.SubscriptionId, resolvedSubscription, _cacheEntryOptions);

            // generate fake token
            var    json           = JsonConvert.SerializeObject(resolvedSubscription);
            var    plainTextBytes = Encoding.UTF8.GetBytes(json);
            var    base64String   = Convert.ToBase64String(plainTextBytes);
            string redirectUrl    = _configuration["SaaSOffer:LandingpageURL"] + "?token=" + base64String;

            return(Redirect(redirectUrl));
        }
        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));
        }