Example #1
0
        public AzureRmProfile Login(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenantId,
            string subscriptionId,
            string subscriptionName,
            SecureString password,
            bool skipValidation,
            Action <string> promptAction,
            string name = null,
            bool shouldPopulateContextList = true,
            int maxContextPopulation       = Profile.ConnectAzureRmAccountCommand.DefaultMaxContextPopulation)
        {
            IAzureSubscription newSubscription = null;
            IAzureTenant       newTenant       = null;
            string             promptBehavior  =
                (password == null &&
                 account.Type != AzureAccount.AccountType.AccessToken &&
                 account.Type != AzureAccount.AccountType.ManagedService &&
                 !account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
                ? ShowDialog.Always : ShowDialog.Never;

            SubscritpionClientCandidates.Reset();

            if (skipValidation)
            {
                if (string.IsNullOrEmpty(subscriptionId) || string.IsNullOrEmpty(tenantId))
                {
                    throw new PSInvalidOperationException(Resources.SubscriptionOrTenantMissing);
                }

                newSubscription = new AzureSubscription
                {
                    Id = subscriptionId
                };

                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Tenants, tenantId);
                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Account, account.Id);

                newTenant = new AzureTenant
                {
                    Id = tenantId
                };
            }
            else
            {
                // (tenant and subscription are present) OR
                // (tenant is present and subscription is not provided)
                if (!string.IsNullOrEmpty(tenantId))
                {
                    Guid tempGuid = Guid.Empty;
                    if (!Guid.TryParse(tenantId, out tempGuid))
                    {
                        var tenants     = ListAccountTenants(account, environment, password, promptBehavior, promptAction);
                        var homeTenants = tenants.FirstOrDefault(t => t.IsHome);
                        var tenant      = homeTenants ?? tenants.FirstOrDefault();
                        if (tenant == null || tenant.Id == null)
                        {
                            string baseMessage    = string.Format(ProfileMessages.TenantDomainNotFound, tenantId);
                            var    typeMessageMap = new Dictionary <string, string>
                            {
                                { AzureAccount.AccountType.ServicePrincipal, string.Format(ProfileMessages.ServicePrincipalTenantDomainNotFound, account.Id) },
                                { AzureAccount.AccountType.User, ProfileMessages.UserTenantDomainNotFound },
                                { AzureAccount.AccountType.ManagedService, ProfileMessages.MSITenantDomainNotFound }
                            };
                            string typeMessage = typeMessageMap.ContainsKey(account.Type) ? typeMessageMap[account.Type] : string.Empty;
                            throw new ArgumentNullException(string.Format("{0} {1}", baseMessage, typeMessage));
                        }

                        tenantId = tenant.Id;
                    }


                    var token = AcquireAccessToken(
                        account,
                        environment,
                        tenantId,
                        password,
                        promptBehavior,
                        promptAction);
                    if (TryGetTenantSubscription(
                            token,
                            account,
                            environment,
                            subscriptionId,
                            subscriptionName,
                            true,
                            out newSubscription,
                            out newTenant))
                    {
                        account.SetOrAppendProperty(AzureAccount.Property.Tenants, new[] { newTenant.Id.ToString() });
                    }
                }
                // (tenant is not provided and subscription is present) OR
                // (tenant is not provided and subscription is not provided)
                else
                {
                    var tenants = ListAccountTenants(account, environment, password, promptBehavior, promptAction)
                                  .Select(s => s.Id.ToString()).ToList();
                    account.SetProperty(AzureAccount.Property.Tenants, null);
                    string             accountId        = null;
                    IAzureTenant       tempTenant       = null;
                    IAzureSubscription tempSubscription = null;
                    foreach (var tenant in tenants)
                    {
                        tempTenant       = null;
                        tempSubscription = null;

                        IAccessToken token = null;

                        try
                        {
                            token = AcquireAccessToken(account, environment, tenant, password, ShowDialog.Auto, null);
                            if (accountId == null)
                            {
                                accountId = account.Id;
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else if (accountId.Equals(account.Id, StringComparison.OrdinalIgnoreCase))
                            {
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else
                            {   // if account ID is different from the first tenant account id we need to ignore current tenant
                                WriteWarningMessage(string.Format(
                                                        ProfileMessages.AccountIdMismatch,
                                                        account.Id,
                                                        tenant,
                                                        accountId));
                                account.Id = accountId;
                                token      = null;
                            }
                        }
                        catch
                        {
                            WriteWarningMessage(string.Format(ProfileMessages.UnableToAqcuireToken, tenant));
                        }

                        if (token != null &&
                            newTenant == null &&
                            TryGetTenantSubscription(token, account, environment, subscriptionId, subscriptionName, false, out tempSubscription, out tempTenant))
                        {
                            // If no subscription found for the given token/tenant,discard tempTenant value.
                            // Continue to look for matched subscripitons until one subscription retrived by its home tenant is found.
                            if (tempSubscription != null)
                            {
                                newSubscription = tempSubscription;
                                if (tempSubscription.GetTenant() == tempSubscription.GetHomeTenant())
                                {
                                    newTenant = tempTenant;
                                }
                            }
                        }
                    }
                    newSubscription = newSubscription ?? tempSubscription;
                    newTenant       = newTenant ??
                                      (newSubscription != null ? new AzureTenant()
                    {
                        Id = newSubscription.GetTenant()
                    } : tempTenant);
                }
            }

            shouldPopulateContextList &= _profile.DefaultContext?.Account == null;
            if (newSubscription == null)
            {
                if (subscriptionId != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionIdNotFound, account.Id, subscriptionId));
                }
                else if (subscriptionName != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionNameNotFound, account.Id, subscriptionName));
                }

                var newContext = new AzureContext(account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }
            }
            else
            {
                var newContext = new AzureContext(newSubscription, account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }

                if (!skipValidation && !newSubscription.State.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
                {
                    WriteWarningMessage(string.Format(
                                            ProfileMessages.SelectedSubscriptionNotActive,
                                            newSubscription.State));
                }
            }

            _profile.DefaultContext.TokenCache = _cache;
            if (shouldPopulateContextList && maxContextPopulation != 0)
            {
                var defaultContext = _profile.DefaultContext;
                var subscriptions  = maxContextPopulation > 0 ? ListSubscriptions(tenantId).Take(maxContextPopulation) : ListSubscriptions(tenantId);

                foreach (var subscription in subscriptions)
                {
                    IAzureTenant tempTenant = new AzureTenant()
                    {
                        Id = subscription.GetProperty(AzureSubscription.Property.Tenants)
                    };

                    var tempContext = new AzureContext(subscription, account, environment, tempTenant);
                    tempContext.TokenCache = _cache;
                    string tempName = null;
                    if (!_profile.TryGetContextName(tempContext, out tempName))
                    {
                        WriteWarningMessage(string.Format(Resources.CannotGetContextName, subscription.Id));
                        continue;
                    }

                    if (!_profile.TrySetContext(tempName, tempContext))
                    {
                        WriteWarningMessage(string.Format(Resources.CannotCreateContext, subscription.Id));
                    }
                }

                _profile.TrySetDefaultContext(defaultContext);
                _profile.TryRemoveContext("Default");
            }

            return(_profile.ToProfile());
        }