示例#1
0
        /// <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);
        }