mirror of
https://github.com/bitwarden/server
synced 2025-12-06 00:03:34 +00:00
[BEEEP] [PM-28808] Fix invalid identity URL in Swagger (#6653)
- in generated JSON (used in help center), only show cloud options (with corrected identity URL) - in self-host and dev, only show local option
This commit is contained in:
@@ -18,11 +18,11 @@ if ($LASTEXITCODE -ne 0) {
|
||||
# Api internal & public
|
||||
Set-Location "../../src/Api"
|
||||
dotnet build
|
||||
dotnet swagger tofile --output "../../api.json" --host "https://api.bitwarden.com" "./bin/Debug/net8.0/Api.dll" "internal"
|
||||
dotnet swagger tofile --output "../../api.json" "./bin/Debug/net8.0/Api.dll" "internal"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
dotnet swagger tofile --output "../../api.public.json" --host "https://api.bitwarden.com" "./bin/Debug/net8.0/Api.dll" "public"
|
||||
dotnet swagger tofile --output "../../api.public.json" "./bin/Debug/net8.0/Api.dll" "public"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public class Startup
|
||||
config.Conventions.Add(new PublicApiControllersModelConvention());
|
||||
});
|
||||
|
||||
services.AddSwagger(globalSettings, Environment);
|
||||
services.AddSwaggerGen(globalSettings, Environment);
|
||||
Jobs.JobsHostedService.AddJobsServices(services, globalSettings.SelfHosted);
|
||||
services.AddHostedService<Jobs.JobsHostedService>();
|
||||
|
||||
@@ -292,17 +292,59 @@ public class Startup
|
||||
});
|
||||
|
||||
// Add Swagger
|
||||
// Note that the swagger.json generation is configured in the call to AddSwaggerGen above.
|
||||
if (Environment.IsDevelopment() || globalSettings.SelfHosted)
|
||||
{
|
||||
// adds the middleware to serve the swagger.json while the server is running
|
||||
app.UseSwagger(config =>
|
||||
{
|
||||
config.RouteTemplate = "specs/{documentName}/swagger.json";
|
||||
|
||||
// Remove all Bitwarden cloud servers and only register the local server
|
||||
config.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
|
||||
swaggerDoc.Servers = new List<OpenApiServer>
|
||||
{
|
||||
swaggerDoc.Servers.Clear();
|
||||
swaggerDoc.Servers.Add(new OpenApiServer
|
||||
{
|
||||
new OpenApiServer { Url = globalSettings.BaseServiceUri.Api }
|
||||
Url = globalSettings.BaseServiceUri.Api,
|
||||
});
|
||||
|
||||
swaggerDoc.Components.SecuritySchemes.Clear();
|
||||
swaggerDoc.Components.SecuritySchemes.Add("oauth2-client-credentials", new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
Flows = new OpenApiOAuthFlows
|
||||
{
|
||||
ClientCredentials = new OpenApiOAuthFlow
|
||||
{
|
||||
TokenUrl = new Uri($"{globalSettings.BaseServiceUri.Identity}/connect/token"),
|
||||
Scopes = new Dictionary<string, string>
|
||||
{
|
||||
{ ApiScopes.ApiOrganization, "Organization APIs" }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
swaggerDoc.SecurityRequirements.Clear();
|
||||
swaggerDoc.SecurityRequirements.Add(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "oauth2-client-credentials"
|
||||
}
|
||||
},
|
||||
[ApiScopes.ApiOrganization]
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// adds the middleware to display the web UI
|
||||
app.UseSwaggerUI(config =>
|
||||
{
|
||||
config.DocumentTitle = "Bitwarden API Documentation";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Bit.Api.AdminConsole.Authorization;
|
||||
using Bit.Api.Tools.Authorization;
|
||||
using Bit.Core.Auth.IdentityServer;
|
||||
using Bit.Core.PhishingDomainFeatures;
|
||||
using Bit.Core.PhishingDomainFeatures.Interfaces;
|
||||
using Bit.Core.Repositories;
|
||||
@@ -10,6 +9,7 @@ using Bit.Core.Utilities;
|
||||
using Bit.Core.Vault.Authorization.SecurityTasks;
|
||||
using Bit.SharedWeb.Health;
|
||||
using Bit.SharedWeb.Swagger;
|
||||
using Bit.SharedWeb.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
@@ -17,7 +17,10 @@ namespace Bit.Api.Utilities;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static void AddSwagger(this IServiceCollection services, GlobalSettings globalSettings, IWebHostEnvironment environment)
|
||||
/// <summary>
|
||||
/// Configures the generation of swagger.json OpenAPI spec.
|
||||
/// </summary>
|
||||
public static void AddSwaggerGen(this IServiceCollection services, GlobalSettings globalSettings, IWebHostEnvironment environment)
|
||||
{
|
||||
services.AddSwaggerGen(config =>
|
||||
{
|
||||
@@ -36,6 +39,8 @@ public static class ServiceCollectionExtensions
|
||||
organizations tools for managing members, collections, groups, event logs, and policies.
|
||||
If you are looking for the Vault Management API, refer instead to
|
||||
[this document](https://bitwarden.com/help/vault-management-api/).
|
||||
|
||||
**Note:** your authorization must match the server you have selected.
|
||||
""",
|
||||
License = new OpenApiLicense
|
||||
{
|
||||
@@ -46,36 +51,20 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
config.SwaggerDoc("internal", new OpenApiInfo { Title = "Bitwarden Internal API", Version = "latest" });
|
||||
|
||||
config.AddSecurityDefinition("oauth2-client-credentials", new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
Flows = new OpenApiOAuthFlows
|
||||
{
|
||||
ClientCredentials = new OpenApiOAuthFlow
|
||||
{
|
||||
TokenUrl = new Uri($"{globalSettings.BaseServiceUri.Identity}/connect/token"),
|
||||
Scopes = new Dictionary<string, string>
|
||||
{
|
||||
{ ApiScopes.ApiOrganization, "Organization APIs" },
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
// Configure Bitwarden cloud US and EU 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).
|
||||
config.AddSwaggerServerWithSecurity(
|
||||
serverId: "US_server",
|
||||
serverUrl: "https://api.bitwarden.com",
|
||||
identityTokenUrl: "https://identity.bitwarden.com/connect/token",
|
||||
serverDescription: "US server");
|
||||
|
||||
config.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "oauth2-client-credentials"
|
||||
},
|
||||
},
|
||||
new[] { ApiScopes.ApiOrganization }
|
||||
}
|
||||
});
|
||||
config.AddSwaggerServerWithSecurity(
|
||||
serverId: "EU_server",
|
||||
serverUrl: "https://api.bitwarden.eu",
|
||||
identityTokenUrl: "https://identity.bitwarden.eu/connect/token",
|
||||
serverDescription: "EU server");
|
||||
|
||||
config.DescribeAllParametersInCamelCase();
|
||||
// config.UseReferencedDefinitionsForEnums();
|
||||
|
||||
@@ -85,7 +85,9 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using StackExchange.Redis;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
using NoopRepos = Bit.Core.Repositories.Noop;
|
||||
using Role = Bit.Core.Entities.Role;
|
||||
@@ -1067,4 +1069,61 @@ public static class ServiceCollectionExtensions
|
||||
CoreHelpers.SettingHasValue(settings.EventLogging.RabbitMq.Password) &&
|
||||
CoreHelpers.SettingHasValue(settings.EventLogging.RabbitMq.EventExchangeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a server with its corresponding OAuth2 client credentials security definition and requirement.
|
||||
/// </summary>
|
||||
/// <param name="config">The SwaggerGen configuration</param>
|
||||
/// <param name="serverId">Unique identifier for this server (e.g., "us-server", "eu-server")</param>
|
||||
/// <param name="serverUrl">The API server URL</param>
|
||||
/// <param name="identityTokenUrl">The identity server token URL</param>
|
||||
/// <param name="serverDescription">Human-readable description for the server</param>
|
||||
public static void AddSwaggerServerWithSecurity(
|
||||
this SwaggerGenOptions config,
|
||||
string serverId,
|
||||
string serverUrl,
|
||||
string identityTokenUrl,
|
||||
string serverDescription)
|
||||
{
|
||||
// Add server
|
||||
config.AddServer(new OpenApiServer
|
||||
{
|
||||
Url = serverUrl,
|
||||
Description = serverDescription
|
||||
});
|
||||
|
||||
// Add security definition
|
||||
config.AddSecurityDefinition(serverId, new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
Description = $"**Use this option if you've selected the {serverDescription}**",
|
||||
Flows = new OpenApiOAuthFlows
|
||||
{
|
||||
ClientCredentials = new OpenApiOAuthFlow
|
||||
{
|
||||
TokenUrl = new Uri(identityTokenUrl),
|
||||
Scopes = new Dictionary<string, string>
|
||||
{
|
||||
{ ApiScopes.ApiOrganization, $"Organization APIs ({serverDescription})" },
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Add security requirement
|
||||
config.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = serverId
|
||||
},
|
||||
},
|
||||
[ApiScopes.ApiOrganization]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user