/// <summary> /// Update the non-identity properties of this tenant, using another tenant /// </summary> /// <param name="tenant"></param> /// <param name="other"></param> public static void Update(this IAzureTenant tenant, IAzureTenant other) { if (tenant != null && other != null) { tenant.UpdateProperties(other); } }
private async IAsyncEnumerable <JsonElement> GetArrayAsync(IAzureTenant tenant, string nextLink, ListRequestOptions?options, [EnumeratorCancellation] CancellationToken cancellationToken) { string?link = nextLink; var reqOptions = new RequestHeaderOptions { ConsistencyLevelEventual = options?.ConsistencyLevelEventual ?? false }; do { var root = await GetAsync(tenant, link, reqOptions, cancellationToken).ConfigureAwait(false); options?.OnPageReceived(root); foreach (var item in root.GetProperty("value").EnumerateArray()) { if (cancellationToken.IsCancellationRequested) { yield break; } yield return(item); } HandleNextLink(root, ref link); } while (link != null); }
private async Task <JsonElement> SendAsync(IAzureTenant tenant, HttpMethod method, ReadOnlyMemory <byte>?utf8Data, string requestUri, RequestHeaderOptions?options, CancellationToken cancellationToken) { using var response = await SendInternalAsync(tenant, method, utf8Data, requestUri, options, cancellationToken); if (response.StatusCode == HttpStatusCode.NoContent || response.Content.Headers.ContentLength == 0) { logger.LogInformation("Got no content for HTTP request to {requestUri}.", requestUri); return(default);
async Task <string> ISlimGraphMobileAppsClient.CreateMobileAppContentAsync(IAzureTenant tenant, Guid appID, string type, InvokeRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"deviceAppManagement/mobileApps/{appID}/{type}/contentVersions"); var response = await PostAsync(tenant, new byte[] { 0x7B, 0x7D }, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false); return(response.GetProperty("id").GetString()); }
/// <summary> /// Copy tenaht properties from another tenant /// </summary> /// <param name="tenant"></param> /// <param name="other"></param> public static void CopyFrom(this IAzureTenant tenant, IAzureTenant other) { if (tenant != null && other != null) { tenant.Id = other.Id; tenant.CopyPropertiesFrom(other); } }
/// <summary> /// Creates new instance of AzureContext. /// </summary> /// <param name="subscription">The azure subscription object</param> /// <param name="account">The azure account object</param> /// <param name="environment">The azure environment object</param> /// <param name="tenant">The azure tenant object</param> public AzureContext(IAzureSubscription subscription, IAzureAccount account, IAzureEnvironment environment, IAzureTenant tenant, byte[] tokens) { Subscription = subscription; Account = account; Environment = environment; Tenant = tenant; TokenCache = new AzureTokenCache(); TokenCache.CacheData = tokens; }
public static IAzureContext WithTenant(this IAzureContext context, IAzureTenant tenant) { if (tenant != null && !string.IsNullOrWhiteSpace(tenant.Id) && context != null) { context.Subscription?.SetTenant(tenant.Id); context.Account?.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant.Id); context.Tenant = tenant; } return(context); }
async IAsyncEnumerable <JsonElement> ISlimGraphUsersClient.GetMemberOfAsync(IAzureTenant tenant, Guid userID, ListRequestOptions?options, [EnumeratorCancellation] CancellationToken cancellationToken) { var nextLink = BuildLink(options, $"users/{userID}/memberOf"); await foreach (var item in GetArrayAsync(tenant, nextLink, options, cancellationToken)) { if (cancellationToken.IsCancellationRequested) { yield break; } yield return(item); } }
async Task ISlimGraphMobileAppsClient.CommitMobileAppContentAsync(IAzureTenant tenant, Guid appID, string type, string mobileAppContentID, InvokeRequestOptions?options, CancellationToken cancellationToken) { var buffer = new ArrayBufferWriter <byte>(); using (var writer = new Utf8JsonWriter(buffer)) { writer.WriteStartObject(); writer.WriteString("@odata.type", "#" + type); writer.WriteString("committedContentVersion", mobileAppContentID); writer.WriteEndObject(); } await((ISlimGraphMobileAppsClient)this).UpdateMobileAppAsync(tenant, appID, JsonSerializer.Deserialize <JsonElement>(buffer.WrittenSpan)); }
async IAsyncEnumerable <JsonElement> ISlimGraphGroupsClient.GetGroupsAsync(IAzureTenant tenant, ListRequestOptions?options, [EnumeratorCancellation] CancellationToken cancellationToken) { var nextLink = BuildLink(options, "groups"); await foreach (var item in GetArrayAsync(tenant, nextLink, options, cancellationToken)) { if (cancellationToken.IsCancellationRequested) { yield break; } yield return(item); } }
async Task <SlimGraphPicture?> ISlimGraphUsersClient.GetUserPhotoDataAsync(IAzureTenant tenant, Guid userID, string size, ScalarRequestOptions?options, CancellationToken cancellationToken) { string link; if (string.IsNullOrEmpty(size)) { link = BuildLink(options, $"users/{userID}/photo/$value"); } else { link = BuildLink(options, $"users/{userID}/photos/{size}/$value"); } return(await GetPictureAsync(tenant, link, cancellationToken).ConfigureAwait(false)); }
async Task ISlimGraphGroupsClient.AddMemberAsync(IAzureTenant tenant, Guid groupID, Guid memberID, InvokeRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"groups/{groupID}/members/$ref"); var buffer = new ArrayBufferWriter <byte>(); using (var writer = new Utf8JsonWriter(buffer)) { writer.WriteStartObject(); writer.WriteString("@odata.id", httpClient.BaseAddress + "directoryObjects/" + memberID); writer.WriteEndObject(); } await PostAsync(tenant, buffer.WrittenMemory, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false); }
async Task <JsonElement> ISlimGraphUsersClient.GetUserPhotoAsync(IAzureTenant tenant, Guid userID, string size, ScalarRequestOptions?options, CancellationToken cancellationToken) { string link; if (string.IsNullOrEmpty(size)) { link = BuildLink(options, $"users/{userID}/photo"); } else { link = BuildLink(options, $"users/{userID}/photos/{size}"); } return(await GetAsync(tenant, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false)); }
public Task <AuthSuccessResponse> GetAuthenticationAsync(IAzureTenant tenant, string scope) { if (memoryCache != null) { var key = nameof(AzureAuthenticationClient) + nameof(GetAuthenticationAsync) + tenant.Identifier + scope; return(memoryCache.GetOrCreateAsync(key, async entry => { var response = await GetAuthenticationImplAsync(tenant, scope); entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(response.ExpiresIn - MinTokenLifetimeSeconds)); return response; })); } return(GetAuthenticationImplAsync(tenant, scope)); }
private async Task <AuthSuccessResponse> GetAuthenticationImplAsync(IAzureTenant tenant, string scope) { var data = azureCredentials.GetRequestData(scope); using var content = new FormUrlEncodedContent(data); using var response = await httpClient.PostAsync(tenant.TokenUrl, content).ConfigureAwait(false); using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); if (!response.IsSuccessStatusCode) { var error = await JsonSerializer.DeserializeAsync <AuthErrorResponse>(stream).ConfigureAwait(false); throw new AuthException(response.StatusCode, error.Error ?? "No more details available.", error.ErrorDescription ?? "No more details available."); } return(await JsonSerializer.DeserializeAsync <AuthSuccessResponse>(stream).ConfigureAwait(false)); }
public IAzureContext SetCurrentContext(string subscriptionNameOrId, string tenantId, string name = null) { IAzureSubscription subscription = null; IAzureTenant tenant = null; Guid subscriptionId; IAzureContext context = new AzureContext(); context.CopyFrom(_profile.DefaultContext); if (!string.IsNullOrWhiteSpace(subscriptionNameOrId)) { if (Guid.TryParse(subscriptionNameOrId, out subscriptionId)) { TryGetSubscriptionById(tenantId, subscriptionNameOrId, out subscription); } else { TryGetSubscriptionByName(tenantId, subscriptionNameOrId, out subscription); } if (subscription == null) { throw new ArgumentException(ProfileMessages.SubscriptionOrTenantRequired); } var tenantFromSubscription = subscription.GetTenant(); tenant = string.IsNullOrWhiteSpace(tenantId) ? (string.IsNullOrEmpty(tenantFromSubscription) ? context.Tenant : CreateTenant(tenantFromSubscription)): CreateTenant(tenantId); } else if (!string.IsNullOrWhiteSpace(tenantId)) { subscription = GetFirstSubscription(tenantId); tenant = CreateTenant(tenantId); } else { throw new ArgumentException(ProfileMessages.SubscriptionOrTenantRequired); } context.WithTenant(tenant).WithSubscription(subscription); _profile.TrySetDefaultContext(name, context); _profile.DefaultContext.ExtendedProperties.Clear(); return(context); }
/// <summary> /// Creates credential instance for given subscription /// </summary> private ServiceClientCredentials CreateCredentials(IAzureTenant tenant) { AzureTenant azureTenant = tenant as AzureTenant; if (azureTenant != null) { TokenCredentials credentials; if (!string.IsNullOrWhiteSpace(azureTenant.TokenType)) { credentials = new TokenCredentials(azureTenant.AccessToken, azureTenant.TokenType); } else { credentials = new TokenCredentials(azureTenant.AccessToken); } return(credentials); } throw new NotSupportedException("This uses an unknown subscription type"); }
private async Task <DeltaResult <JsonElement> > GetDeltaAsync(IAzureTenant tenant, string nextLink, DeltaRequestOptions?options, CancellationToken cancellationToken) { var result = new List <JsonElement>(); string?nLink = nextLink; string?dLink = default; RequestHeaderOptions?reqOptions = null; if (options?.PreferMinimal == true) { reqOptions = new RequestHeaderOptions { PreferMinimal = true }; } do { var root = await GetAsync(tenant, nLink, reqOptions, cancellationToken).ConfigureAwait(false); foreach (var item in root.GetProperty("value").EnumerateArray()) { if (cancellationToken.IsCancellationRequested) { break; } result.Add(item); } if (cancellationToken.IsCancellationRequested) { break; } HandleNextLink(root, ref nLink); HandleDeltaLink(root, ref dLink); } while (nLink != null); return(new DeltaResult <JsonElement>(result, dLink)); }
private async IAsyncEnumerable <JsonElement> PostArrayAsync(IAzureTenant tenant, ReadOnlyMemory <byte> utf8Data, string nextLink, RequestHeaderOptions?options, [EnumeratorCancellation] CancellationToken cancellationToken) { string?nLink = nextLink; do { var root = await PostAsync(tenant, utf8Data, nLink, options, cancellationToken).ConfigureAwait(false); foreach (var item in root.GetProperty("value").EnumerateArray()) { if (cancellationToken.IsCancellationRequested) { yield break; } yield return(item); } HandleNextLink(root, ref nLink); } while (nLink != null); }
async Task ISlimGraphGroupsClient.AddMembersAsync(IAzureTenant tenant, Guid groupID, IEnumerable <Guid> memberIDs, InvokeRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"groups/{groupID}"); var buffer = new ArrayBufferWriter <byte>(); using (var writer = new Utf8JsonWriter(buffer)) { writer.WriteStartObject(); writer.WriteStartArray("*****@*****.**"); foreach (var memberID in memberIDs) { writer.WriteStringValue(httpClient.BaseAddress + "directoryObjects/" + memberID); } writer.WriteEndArray(); writer.WriteEndObject(); } await PatchAsync(tenant, buffer.WrittenMemory, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false); }
private async Task <ServiceResponse <IAzureUserAccountSubscriptionContext> > GetSubscriptionsForTentantAsync( IAzureUserAccount userAccount, IAzureTenant tenant, string lookupKey, CancellationToken cancellationToken, CancellationToken internalCancellationToken) { AzureTenant azureTenant = tenant as AzureTenant; if (azureTenant != null) { ServiceClientCredentials credentials = CreateCredentials(azureTenant); using (SubscriptionClient client = new SubscriptionClient(_resourceManagementUri, credentials)) { IEnumerable <Subscription> subs = await GetSubscriptionsAsync(client); return(new ServiceResponse <IAzureUserAccountSubscriptionContext>(subs.Select(sub => { AzureSubscriptionIdentifier subId = new AzureSubscriptionIdentifier(userAccount, azureTenant.TenantId, sub.SubscriptionId, _resourceManagementUri); AzureUserAccountSubscriptionContext context = new AzureUserAccountSubscriptionContext(subId, credentials); return context; }))); } } return(new ServiceResponse <IAzureUserAccountSubscriptionContext>()); }
private async IAsyncEnumerable <Guid> GetMemberObjectsImplAsync(IAzureTenant tenant, object id, bool securityEnabledOnly, InvokeRequestOptions?options, [EnumeratorCancellation] CancellationToken cancellationToken) { var nextLink = BuildLink(options, $"users/{id}/getMemberObjects"); var buffer = new ArrayBufferWriter <byte>(); using (var writer = new Utf8JsonWriter(buffer)) { writer.WriteStartObject(); writer.WriteBoolean("securityEnabledOnly", securityEnabledOnly); writer.WriteEndObject(); } await foreach (var item in PostArrayAsync(tenant, buffer.WrittenMemory, nextLink, new RequestHeaderOptions(), cancellationToken)) { if (cancellationToken.IsCancellationRequested) { yield break; } yield return(item.GetGuid()); } }
private async Task <ServiceResponse <IAzureUserAccountSubscriptionContext> > GetSubscriptionsForTentantAsync( IAzureUserAccount userAccount, IAzureTenant tenant, string lookupKey, CancellationToken cancellationToken, CancellationToken internalCancellationToken) { AzureTenant azureTenant = tenant as AzureTenant; if (azureTenant != null) { ServiceClientCredentials credentials = CreateCredentials(azureTenant); string armEndpoint = userAccount.UnderlyingAccount.Properties.ProviderSettings?.Settings?.ArmResource?.Endpoint; Uri armUri = null; if (armEndpoint != null) { try { armUri = new Uri(armEndpoint); } catch (Exception e) { Console.WriteLine($"Exception while parsing URI: {e.Message}"); } } using (SubscriptionClient client = new SubscriptionClient(armUri ?? _resourceManagementUri, credentials)) { IEnumerable <Subscription> subs = await GetSubscriptionsAsync(client); return(new ServiceResponse <IAzureUserAccountSubscriptionContext>(subs.Select(sub => { AzureSubscriptionIdentifier subId = new AzureSubscriptionIdentifier(userAccount, azureTenant.TenantId, sub.SubscriptionId, armUri ?? _resourceManagementUri); AzureUserAccountSubscriptionContext context = new AzureUserAccountSubscriptionContext(subId, credentials); return context; }))); } } return(new ServiceResponse <IAzureUserAccountSubscriptionContext>()); }
private bool TryGetTenantSubscription(IAccessToken accessToken, IAzureAccount account, IAzureEnvironment environment, string tenantId, string subscriptionId, string subscriptionName, out IAzureSubscription subscription, out IAzureTenant tenant) { using (var subscriptionClient = AzureSession.Instance.ClientFactory.CreateCustomArmClient <SubscriptionClient>( environment.GetEndpointAsUri(AzureEnvironment.Endpoint.ResourceManager), new TokenCredentials(accessToken.AccessToken) as ServiceClientCredentials, AzureSession.Instance.ClientFactory.GetCustomHandlers())) { Subscription subscriptionFromServer = null; try { if (subscriptionId != null) { subscriptionFromServer = subscriptionClient.Subscriptions.Get(subscriptionId); } else { var subscriptions = (subscriptionClient.ListAll().ToList() ?? new List <Subscription>()) .Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) || "warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase)); account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions.Select(i => i.SubscriptionId).ToArray()); if (subscriptions.Any()) { if (subscriptionName != null) { subscriptionFromServer = subscriptions.FirstOrDefault( s => s.DisplayName.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase)); } else { if (subscriptions.Count() > 1) { WriteWarningMessage(string.Format( "TenantId '{0}' contains more than one active subscription. First one will be selected for further use. " + "To select another subscription, use Set-AzureRmContext.", tenantId)); } subscriptionFromServer = subscriptions.First(); } } } } catch (CloudException ex) { WriteWarningMessage(ex.Message); } if (subscriptionFromServer != null) { subscription = new AzureSubscription { Id = subscriptionFromServer.SubscriptionId, Name = subscriptionFromServer.DisplayName, State = subscriptionFromServer.State.ToString() }; subscription.SetAccount(accessToken.UserId); subscription.SetEnvironment(environment.Name); subscription.SetTenant(accessToken.TenantId); tenant = new AzureTenant(); tenant.Id = accessToken.TenantId; tenant.Directory = accessToken.GetDomain(); return(true); } subscription = null; if (accessToken != null && accessToken.TenantId != null) { tenant = new AzureTenant(); tenant.Id = accessToken.TenantId; if (accessToken.UserId != null) { var domain = accessToken.UserId.Split(new[] { '@' }, StringSplitOptions.RemoveEmptyEntries); if (domain.Length == 2) { tenant.Directory = domain[1]; } } return(true); } tenant = null; return(false); } }
public AzureRmProfile Login( IAzureAccount account, IAzureEnvironment environment, string tenantId, string subscriptionId, string subscriptionName, SecureString password, bool skipValidation, Action <string> promptAction, string name = null) { 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; 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)) { var token = AcquireAccessToken( account, environment, tenantId, password, promptBehavior, promptAction); if (TryGetTenantSubscription( token, account, environment, tenantId, subscriptionId, subscriptionName, 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; foreach (var tenant in tenants) { IAzureTenant tempTenant; IAzureSubscription tempSubscription; 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, tenant, subscriptionId, subscriptionName, out tempSubscription, out tempTenant)) { // If no subscription found for the given token/tenant // discard tempTenant value unless current token/tenant is the last one. if (tempSubscription != null || tenant.Equals(tenants[tenants.Count - 1])) { newTenant = tempTenant; newSubscription = tempSubscription; } } } } } 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; return(_profile.ToProfile()); }
async Task <JsonElement> ISlimGraphServicePrincipalsClient.GetServicePrincipalAsync(IAzureTenant tenant, Guid servicePrincipalID, ScalarRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"servicePrincipals/{servicePrincipalID}"); return(await GetAsync(tenant, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Get the tenant Id as a Guid /// </summary> /// <param name="tenant">The tenant to check</param> /// <returns>The tenant ID as a Guid</returns> public static Guid GetId(this IAzureTenant tenant) { return(tenant.Id == null? Guid.Empty: new Guid(tenant.Id)); }
async Task <JsonElement> ISlimGraphAuditLogsClient.GetSignInAsync(IAzureTenant tenant, Guid signInID, ScalarRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"auditLogs/signIns/{signInID}"); return(await GetAsync(tenant, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false)); }
async Task <JsonElement> ISlimGraphDirectoryRolesClient.GetDirectoryRoleAsync(IAzureTenant tenant, Guid directoryRoleID, ScalarRequestOptions?options, CancellationToken cancellationToken) { var link = BuildLink(options, $"directoryRoles/{directoryRoleID}"); return(await GetAsync(tenant, link, new RequestHeaderOptions(), cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Copy Constructor /// </summary> /// <param name="other">The tenanht to copy</param> public PSAzureTenant(IAzureTenant other) { this.CopyFrom(other); }