diff --git a/src/Api/Api.csproj b/src/Api/Api.csproj
index 44e91565ad..a9e60ac9f0 100644
--- a/src/Api/Api.csproj
+++ b/src/Api/Api.csproj
@@ -14,6 +14,11 @@
+
+
+
+
+
diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs
index f23015cd3e..316d344f0c 100644
--- a/src/Api/Startup.cs
+++ b/src/Api/Startup.cs
@@ -14,6 +14,7 @@ using Stripe;
using Bit.Core.Utilities;
using IdentityModel;
using Microsoft.AspNetCore.HttpOverrides;
+using Swashbuckle.AspNetCore.Swagger;
namespace Bit.Api
{
@@ -110,10 +111,13 @@ namespace Bit.Api
// MVC
services.AddMvc(config =>
{
+ config.Conventions.Add(new ApiExplorerGroupConvention());
config.Filters.Add(new ExceptionHandlerFilterAttribute());
config.Filters.Add(new ModelStateValidationFilterAttribute());
}).AddJsonOptions(o => o.SerializerSettings.ContractResolver = new DefaultContractResolver());
+ services.AddSwagger(globalSettings);
+
if(globalSettings.SelfHosted)
{
// Jobs service
@@ -182,6 +186,21 @@ namespace Bit.Api
// Add MVC to the request pipeline.
app.UseMvc();
+
+ if(globalSettings.SelfHosted)
+ {
+ app.UseSwagger(config =>
+ {
+ config.RouteTemplate = "specs/{documentName}/swagger.json";
+ });
+ app.UseSwaggerUI(config =>
+ {
+ config.RoutePrefix = "docs";
+ config.SwaggerEndpoint("/specs/public/swagger.json", "Bitwarden Public API");
+ config.OAuthClientId("accountType.id");
+ config.OAuthClientSecret("secretKey");
+ });
+ }
}
}
}
diff --git a/src/Api/Utilities/ApiExplorerGroupConvention.cs b/src/Api/Utilities/ApiExplorerGroupConvention.cs
new file mode 100644
index 0000000000..5b8d7559ae
--- /dev/null
+++ b/src/Api/Utilities/ApiExplorerGroupConvention.cs
@@ -0,0 +1,13 @@
+using Microsoft.AspNetCore.Mvc.ApplicationModels;
+
+namespace Bit.Api.Utilities
+{
+ public class ApiExplorerGroupConvention : IControllerModelConvention
+ {
+ public void Apply(ControllerModel controller)
+ {
+ var controllerNamespace = controller.ControllerType.Namespace;
+ controller.ApiExplorer.GroupName = controllerNamespace.Contains(".Public.") ? "public" : "internal";
+ }
+ }
+}
diff --git a/src/Api/Utilities/ServiceCollectionExtensions.cs b/src/Api/Utilities/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000000..492b926ddf
--- /dev/null
+++ b/src/Api/Utilities/ServiceCollectionExtensions.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using Bit.Core;
+using Microsoft.Extensions.DependencyInjection;
+using Swashbuckle.AspNetCore.Swagger;
+
+namespace Bit.Api.Utilities
+{
+ public static class ServiceCollectionExtensions
+ {
+ public static void AddSwagger(this IServiceCollection services, GlobalSettings globalSettings)
+ {
+ services.AddSwaggerGen(config =>
+ {
+ config.SwaggerDoc("public", new Info { Title = "Bitwarden Public API", Version = "latest" });
+ // config.SwaggerDoc("internal", new Info { Title = "Bitwarden Internal API", Version = "latest" });
+
+ config.AddSecurityDefinition("OAuth2 Client Credentials", new OAuth2Scheme
+ {
+ Type = "oauth2",
+ Flow = "application",
+ TokenUrl = $"{globalSettings.BaseServiceUri.Identity}/connect/token",
+ Scopes = new Dictionary
+ {
+ { "api.organization", "Organization APIs" },
+ },
+ });
+
+ config.AddSecurityRequirement(new Dictionary>
+ {
+ { "OAuth2 Client Credentials", new[] { "api.organization" } }
+ });
+ });
+ }
+ }
+}