diff --git a/src/Api/Utilities/ServiceCollectionExtensions.cs b/src/Api/Utilities/ServiceCollectionExtensions.cs index b7940fb0b75c..738eaa7099bc 100644 --- a/src/Api/Utilities/ServiceCollectionExtensions.cs +++ b/src/Api/Utilities/ServiceCollectionExtensions.cs @@ -1,5 +1,6 @@ using Bit.Api.AdminConsole.Authorization; using Bit.Api.Tools.Authorization; +using Bit.Core.Enums; using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.Core.Vault.Authorization.Ciphers; @@ -52,7 +53,8 @@ [this document](https://bitwarden.com/help/vault-management-api/). // Configure Bitwarden cloud servers. These will appear in the swagger.json build artifact // used for our help center. These are overwritten with the local server when running in self-hosted // or dev mode (see Api Startup.cs). - foreach (var regionConfig in CloudRegionConfig.All) + // The Gov region is intentionally excluded from the published spec until it is publicly announced. + foreach (var regionConfig in CloudRegionConfig.All.Where(c => c.Region != CloudRegion.Gov)) { config.AddSwaggerServerWithSecurity( serverId: $"{regionConfig.Region}_server", diff --git a/test/Api.Test/Utilities/SwaggerGenServiceCollectionExtensionsTests.cs b/test/Api.Test/Utilities/SwaggerGenServiceCollectionExtensionsTests.cs new file mode 100644 index 000000000000..fbb0d110dd56 --- /dev/null +++ b/test/Api.Test/Utilities/SwaggerGenServiceCollectionExtensionsTests.cs @@ -0,0 +1,48 @@ +using Bit.Api.Utilities; +using Bit.Core.Enums; +using Bit.Core.Settings; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using NSubstitute; +using Swashbuckle.AspNetCore.SwaggerGen; +using Xunit; + +namespace Bit.Api.Test.Utilities; + +public class SwaggerGenServiceCollectionExtensionsTests +{ + [Fact] + public void AddSwaggerGen_ExcludesGovCloudRegionFromServers() + { + var options = BuildSwaggerGenOptions(); + var govRegion = CloudRegionConfig.FindByRegion(CloudRegion.Gov); + + Assert.DoesNotContain(options.SwaggerGeneratorOptions.Servers, s => s.Url == govRegion.ApiUrl); + Assert.DoesNotContain(options.SwaggerGeneratorOptions.SecuritySchemes.Keys, k => k == $"{CloudRegion.Gov}_server"); + } + + [Theory] + [InlineData(CloudRegion.US)] + [InlineData(CloudRegion.EU)] + public void AddSwaggerGen_IncludesPublicCloudRegionServers(CloudRegion region) + { + var options = BuildSwaggerGenOptions(); + var regionConfig = CloudRegionConfig.FindByRegion(region); + + Assert.Contains(options.SwaggerGeneratorOptions.Servers, s => s.Url == regionConfig.ApiUrl); + Assert.Contains($"{region}_server", options.SwaggerGeneratorOptions.SecuritySchemes.Keys); + } + + private static SwaggerGenOptions BuildSwaggerGenOptions() + { + var environment = Substitute.For(); + environment.EnvironmentName.Returns("Production"); + + var services = new ServiceCollection(); + services.AddSwaggerGen(new GlobalSettings(), environment); + + using var provider = services.BuildServiceProvider(); + return provider.GetRequiredService>().Value; + } +}