/// <inheritdoc/> public async Task <ITenant> GetRequestingTenantAsync(string tenantId) { ITenant tenant = await this.GetTenantAsync(tenantId).ConfigureAwait(false); // Validate it's of the expected type. This will throw an ArgumentException if the tenant is not of the expected // type. This is not particularly useful, so we will catch this and instead throw an exception that will result // in a Not Found response. try { tenant.EnsureTenantIsOfType(MarainTenantType.Client, MarainTenantType.Delegated); } catch (ArgumentException) { throw new OpenApiNotFoundException($"The specified tenant Id, '{tenantId}', is of the wrong type for this request"); } // Ensure the tenant is enrolled for the service. if (!tenant.IsEnrolledForService(this.serviceConfiguration.ServiceTenantId)) { throw OpenApiForbiddenException.WithProblemDetails( "Tenant not enrolled for service", $"The tenant with Id '{tenantId}' is not enrolled in the service '{this.serviceConfiguration.ServiceDisplayName}' with Service Tenant Id '{this.serviceConfiguration.ServiceTenantId}'"); } return(tenant); }
public void ThenTheTenantCalledShouldNotHaveTheIdOfTheTenantCalledInItsEnrollments( string enrolledTenantName, string serviceTenantName) { InMemoryTenantProvider tenantProvider = ContainerBindings.GetServiceProvider(this.scenarioContext).GetRequiredService <InMemoryTenantProvider>(); ITenant enrollingTenant = tenantProvider.GetTenantByName(enrolledTenantName) ?? throw new TenantNotFoundException($"Could not find tenant with name '{enrolledTenantName}'"); ITenant serviceTenant = tenantProvider.GetTenantByName(serviceTenantName) ?? throw new TenantNotFoundException($"Could not find tenant with name '{serviceTenantName}'"); Assert.IsFalse(enrollingTenant.IsEnrolledForService(serviceTenant.Id)); }
/// <summary> /// Unenrolls the specified tenant from the service. /// </summary> /// <param name="tenantStore">The tenant store.</param> /// <param name="enrolledTenant">The tenant that is currently enrolled.</param> /// <param name="serviceTenant">The service they need to be unenrolled from.</param> /// <param name="logger">Optional logger.</param> /// <returns>A task which completes when the unenrollment has finished.</returns> public static async Task UnenrollFromServiceAsync( this ITenantStore tenantStore, ITenant enrolledTenant, ITenant serviceTenant, ILogger?logger = null) { if (!enrolledTenant.IsEnrolledForService(serviceTenant.Id)) { throw new InvalidOperationException( $"Cannot unenroll tenant '{enrolledTenant.Name}' with Id '{enrolledTenant.Id}' from service with Id '{serviceTenant.Id}' because it is not currently enrolled"); } logger?.LogDebug( "Unenrolling tenant '{enrolledTenantName}' with Id '{enrolledTenantId}' from service '{serviceTenantName}' with Id '{serviceTenantId}'", enrolledTenant.Name, enrolledTenant.Id, serviceTenant.Name, serviceTenant.Id); var propertiesToRemove = new List <string>(); ServiceManifest manifest = serviceTenant.GetServiceManifest(); // If there are dependencies, we first need to unenroll from each of those and then remove the delegated tenant. if (manifest.DependsOnServiceTenants.Count > 0) { logger?.LogDebug( "Service '{serviceTenantName}' has dependencies. Retrieving delegated tenant for unenrollment.", serviceTenant.Name); string delegatedTenantId = enrolledTenant.GetDelegatedTenantIdForServiceId(serviceTenant.Id); logger?.LogDebug( "Retrieved delegated tenant with Id '{delegatedTenantId}. Unenrolling from dependencies.", delegatedTenantId); foreach (ServiceDependency current in manifest.DependsOnServiceTenants) { await tenantStore.UnenrollFromServiceAsync(delegatedTenantId, current.Id).ConfigureAwait(false); } // Now delete the delegated tenant. logger?.LogDebug( "Deleting delegated tenant with Id '{delegatedTenantId}'.", delegatedTenantId); await tenantStore.DeleteTenantAsync(delegatedTenantId).ConfigureAwait(false); propertiesToRemove.AddRange(enrolledTenant.GetPropertiesToRemoveDelegatedTenantForService(serviceTenant)); } if (manifest.RequiredConfigurationEntries.Count > 0) { // Now remove any config for the service that's being unenrolled from. logger?.LogDebug( "Removing configuration for service '{serviceTenantName}' from '{enrolledTenantName}'", serviceTenant.Name, enrolledTenant.Name); foreach (ServiceManifestRequiredConfigurationEntry current in manifest.RequiredConfigurationEntries) { logger?.LogDebug( "Removing configuration item '{requiredConfigurationEntryKey}' for service '{serviceTenantName}' from '{enrolledTenantName}'", current.Key, serviceTenant.Name, enrolledTenant.Name); propertiesToRemove.AddRange(current.GetPropertiesToRemoveFromTenant(enrolledTenant)); } } // Finally, remove the enrollment entry for the service. logger?.LogDebug( "Removing enrollment entry for service '{serviceTenantName}' from '{enrolledTenantName}'", serviceTenant.Name, enrolledTenant.Name); IEnumerable <KeyValuePair <string, object> > propertiesToChange = enrolledTenant.GetPropertyUpdatesToRemoveServiceEnrollment(serviceTenant.Id); logger?.LogDebug( "Updating tenant '{enrolledTenantName}'", enrolledTenant.Name); await tenantStore.UpdateTenantAsync( enrolledTenant.Id, propertiesToSetOrAdd : propertiesToChange, propertiesToRemove : propertiesToRemove).ConfigureAwait(false); logger?.LogInformation( "Successfully unenrolled tenant '{enrolledTenantName}' with Id '{enrolledTenantId}' from service '{serviceTenantName}' with Id '{serviceTenantId}'", enrolledTenant.Name, enrolledTenant.Id, serviceTenant.Name, serviceTenant.Id); }