♻️ Refactored swagger generation

This commit is contained in:
2025-09-25 23:44:43 +08:00
parent a88d828e21
commit d69c9f9623
25 changed files with 171 additions and 279 deletions

View File

@@ -18,7 +18,7 @@
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4"/> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4"/>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4" />
<PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1"/> <PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3"/> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="NodaTime" Version="3.2.2"/> <PackageReference Include="NodaTime" Version="3.2.2"/>
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0"/> <PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0"/>
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0"/> <PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0"/>

View File

@@ -13,12 +13,16 @@ builder.ConfigureAppKestrel(builder.Configuration);
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(); builder.Services.AddDysonAuth();
builder.Services.AddPublisherService(); builder.Services.AddPublisherService();
builder.Services.AddAccountService(); builder.Services.AddAccountService();
builder.Services.AddDriveService(); builder.Services.AddDriveService();
builder.AddSwaggerManifest(
"DysonNetwork.Develop",
"The developer portal in the Solar Network."
);
var app = builder.Build(); var app = builder.Build();
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
@@ -31,4 +35,6 @@ using (var scope = app.Services.CreateScope())
app.ConfigureAppMiddleware(builder.Configuration); app.ConfigureAppMiddleware(builder.Configuration);
app.UseSwaggerManifest();
app.Run(); app.Run();

View File

@@ -3,6 +3,7 @@ using DysonNetwork.Develop.Identity;
using DysonNetwork.Shared.Auth; using DysonNetwork.Shared.Auth;
using DysonNetwork.Shared.Http; using DysonNetwork.Shared.Http;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.OpenApi.Models;
using Prometheus; using Prometheus;
namespace DysonNetwork.Develop.Startup; namespace DysonNetwork.Develop.Startup;
@@ -14,9 +15,6 @@ public static class ApplicationConfiguration
app.MapMetrics(); app.MapMetrics();
app.MapOpenApi(); app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
app.UseRequestLocalization(); app.UseRequestLocalization();
app.ConfigureForwardedHeaders(configuration); app.ConfigureForwardedHeaders(configuration);

View File

@@ -57,23 +57,7 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddAppAuthentication(this IServiceCollection services) public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
{ {
services.AddCors();
services.AddAuthorization(); services.AddAuthorization();
return services; return services;
} }
public static IServiceCollection AddAppSwagger(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Develop API",
});
});
services.AddOpenApi();
return services;
}
} }

View File

@@ -16,6 +16,9 @@
"127.0.0.1", "127.0.0.1",
"::1" "::1"
], ],
"Swagger": {
"PublicBasePath": "/develop"
},
"Etcd": { "Etcd": {
"Insecure": true "Insecure": true
}, },

View File

@@ -56,8 +56,8 @@
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" /> <PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.9" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.9" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
<PackageReference Include="tusdotnet" Version="2.10.0" /> <PackageReference Include="tusdotnet" Version="2.10.0" />
</ItemGroup> </ItemGroup>

View File

@@ -18,21 +18,20 @@ builder.ConfigureAppKestrel(builder.Configuration, maxRequestBodySize: long.MaxV
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting(); builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(); builder.Services.AddDysonAuth();
builder.Services.AddAccountService(); builder.Services.AddAccountService();
builder.Services.AddAppFileStorage(builder.Configuration); builder.Services.AddAppFileStorage(builder.Configuration);
// Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();
// Add business services
builder.Services.AddAppBusinessServices(); builder.Services.AddAppBusinessServices();
// Add scheduled jobs
builder.Services.AddAppScheduledJobs(); builder.Services.AddAppScheduledJobs();
builder.AddSwaggerManifest(
"DysonNetwork.Drive",
"The file upload and storage service in the Solar Network."
);
var app = builder.Build(); var app = builder.Build();
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
@@ -50,4 +49,6 @@ app.ConfigureAppMiddleware(tusDiskStore);
// Configure gRPC // Configure gRPC
app.ConfigureGrpcServices(); app.ConfigureGrpcServices();
app.UseSwaggerManifest();
app.Run(); app.Run();

View File

@@ -8,10 +8,6 @@ public static class ApplicationBuilderExtensions
{ {
public static WebApplication ConfigureAppMiddleware(this WebApplication app, ITusStore tusStore) public static WebApplication ConfigureAppMiddleware(this WebApplication app, ITusStore tusStore)
{ {
// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();

View File

@@ -61,9 +61,7 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddAppAuthentication(this IServiceCollection services) public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
{ {
services.AddCors();
services.AddAuthorization(); services.AddAuthorization();
return services; return services;
} }
@@ -74,52 +72,6 @@ public static class ServiceCollectionExtensions
return services; return services;
} }
public static IServiceCollection AddAppSwagger(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Dyson Drive",
Description =
"The file service of the Dyson Network. Mainly handling file storage and sharing. Also provide image processing and media analysis. Powered the Solar Network Drive as well.",
TermsOfService = new Uri("https://solsynth.dev/terms"), // Update with actual terms
License = new OpenApiLicense
{
Name = "APGLv3", // Update with actual license
Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.html")
}
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
[]
}
});
});
return services;
}
public static IServiceCollection AddAppFileStorage(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddAppFileStorage(this IServiceCollection services, IConfiguration configuration)
{ {
var tusStorePath = configuration.GetSection("Tus").GetValue<string>("StorePath")!; var tusStorePath = configuration.GetSection("Tus").GetValue<string>("StorePath")!;

View File

@@ -27,15 +27,6 @@
"PublicKeyPath": "Keys/PublicKey.pem", "PublicKeyPath": "Keys/PublicKey.pem",
"PrivateKeyPath": "Keys/PrivateKey.pem" "PrivateKeyPath": "Keys/PrivateKey.pem"
}, },
"OidcProvider": {
"IssuerUri": "https://nt.solian.app",
"PublicKeyPath": "Keys/PublicKey.pem",
"PrivateKeyPath": "Keys/PrivateKey.pem",
"AccessTokenLifetime": "01:00:00",
"RefreshTokenLifetime": "30.00:00:00",
"AuthorizationCodeLifetime": "00:30:00",
"RequireHttpsMetadata": true
},
"Tus": { "Tus": {
"StorePath": "Uploads" "StorePath": "Uploads"
}, },

View File

@@ -44,8 +44,8 @@
<PackageReference Include="EFCore.BulkExtensions" Version="9.0.1"/> <PackageReference Include="EFCore.BulkExtensions" Version="9.0.1"/>
<PackageReference Include="EFCore.BulkExtensions.PostgreSql" Version="9.0.1"/> <PackageReference Include="EFCore.BulkExtensions.PostgreSql" Version="9.0.1"/>
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0"/> <PackageReference Include="EFCore.NamingConventions" Version="9.0.0"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3"/> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3"/> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -15,20 +15,19 @@ builder.ConfigureAppKestrel(builder.Configuration);
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting(); builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddRingService(); builder.Services.AddRingService();
builder.Services.AddDriveService(); builder.Services.AddDriveService();
builder.Services.AddDevelopService(); builder.Services.AddDevelopService();
// Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();
// Add business services
builder.Services.AddAppBusinessServices(builder.Configuration); builder.Services.AddAppBusinessServices(builder.Configuration);
// Add scheduled jobs
builder.Services.AddAppScheduledJobs(); builder.Services.AddAppScheduledJobs();
builder.AddSwaggerManifest(
"DysonNetwork.Pass",
"The authentication and authorization service in the Solar Network."
);
var app = builder.Build(); var app = builder.Build();
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
@@ -46,4 +45,6 @@ app.ConfigureAppMiddleware(builder.Configuration);
// Configure gRPC // Configure gRPC
app.ConfigureGrpcServices(); app.ConfigureGrpcServices();
app.UseSwaggerManifest();
app.Run(); app.Run();

View File

@@ -16,9 +16,6 @@ public static class ApplicationConfiguration
app.MapMetrics(); app.MapMetrics();
app.MapOpenApi(); app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
app.UseRequestLocalization(); app.UseRequestLocalization();
app.ConfigureForwardedHeaders(configuration); app.ConfigureForwardedHeaders(configuration);

View File

@@ -108,7 +108,6 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddAppAuthentication(this IServiceCollection services) public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
{ {
services.AddCors();
services.AddAuthorization(); services.AddAuthorization();
services.AddAuthentication(options => services.AddAuthentication(options =>
{ {
@@ -120,53 +119,6 @@ public static class ServiceCollectionExtensions
return services; return services;
} }
public static IServiceCollection AddAppSwagger(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Dyson Pass",
Description =
"The authentication service of the Dyson Network. Mainly handling authentication and authorization.",
TermsOfService = new Uri("https://solsynth.dev/terms"),
License = new OpenApiLicense
{
Name = "APGLv3",
Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.html")
}
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
[]
}
});
});
services.AddOpenApi();
return services;
}
public static IServiceCollection AddAppFlushHandlers(this IServiceCollection services) public static IServiceCollection AddAppFlushHandlers(this IServiceCollection services)
{ {
services.AddSingleton<FlushBufferService>(); services.AddSingleton<FlushBufferService>();

View File

@@ -31,8 +31,8 @@
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="9.0.4" />
<PackageReference Include="Quartz" Version="3.14.0" /> <PackageReference Include="Quartz" Version="3.14.0" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.14.0" /> <PackageReference Include="Quartz.Extensions.Hosting" Version="3.14.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -16,19 +16,18 @@ builder.ConfigureAppKestrel(builder.Configuration);
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting(); builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(); builder.Services.AddDysonAuth();
builder.Services.AddAccountService(); builder.Services.AddAccountService();
// Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();
// Add business services
builder.Services.AddAppBusinessServices(); builder.Services.AddAppBusinessServices();
// Add scheduled jobs
builder.Services.AddAppScheduledJobs(); builder.Services.AddAppScheduledJobs();
builder.AddSwaggerManifest(
"DysonNetwork.Ring",
"The realtime service in the Solar Network."
);
var app = builder.Build(); var app = builder.Build();
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
@@ -46,4 +45,6 @@ app.ConfigureAppMiddleware(builder.Configuration);
// Configure gRPC // Configure gRPC
app.ConfigureGrpcServices(); app.ConfigureGrpcServices();
app.UseSwaggerManifest();
app.Run(); app.Run();

View File

@@ -1,7 +1,5 @@
using System.Net;
using DysonNetwork.Ring.Services; using DysonNetwork.Ring.Services;
using DysonNetwork.Shared.Http; using DysonNetwork.Shared.Http;
using Microsoft.AspNetCore.HttpOverrides;
namespace DysonNetwork.Ring.Startup; namespace DysonNetwork.Ring.Startup;
@@ -9,11 +7,6 @@ public static class ApplicationConfiguration
{ {
public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration) public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration)
{ {
app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
app.UseRequestLocalization(); app.UseRequestLocalization();
app.ConfigureForwardedHeaders(configuration); app.ConfigureForwardedHeaders(configuration);

View File

@@ -9,7 +9,6 @@ using DysonNetwork.Ring.Notification;
using DysonNetwork.Ring.Services; using DysonNetwork.Ring.Services;
using DysonNetwork.Shared.Cache; using DysonNetwork.Shared.Cache;
using Microsoft.AspNetCore.RateLimiting; using Microsoft.AspNetCore.RateLimiting;
using Microsoft.OpenApi.Models;
using NodaTime; using NodaTime;
using NodaTime.Serialization.SystemTextJson; using NodaTime.Serialization.SystemTextJson;
using StackExchange.Redis; using StackExchange.Redis;
@@ -69,55 +68,7 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddAppAuthentication(this IServiceCollection services) public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
{ {
services.AddCors();
services.AddAuthorization(); services.AddAuthorization();
return services;
}
public static IServiceCollection AddAppSwagger(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Dyson Ring",
Description = "The pusher service of the Dyson Network. Mainly handling emailing, notifications and websockets.",
TermsOfService = new Uri("https://solsynth.dev/terms"),
License = new OpenApiLicense
{
Name = "APGLv3",
Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.html")
}
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
[]
}
});
});
services.AddOpenApi();
return services; return services;
} }

View File

@@ -27,6 +27,8 @@
<PackageReference Include="NodaTime.Serialization.Protobuf" Version="2.0.2" /> <PackageReference Include="NodaTime.Serialization.Protobuf" Version="2.0.2" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" /> <PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="OpenGraph-Net" Version="4.0.1" /> <PackageReference Include="OpenGraph-Net" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
<PackageReference Include="System.Net.Http" Version="4.3.4" /> <PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" /> <PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" />
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,117 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
namespace DysonNetwork.Shared.Http;
public static class SwaggerGen
{
public static WebApplicationBuilder AddSwaggerManifest(
this WebApplicationBuilder builder,
string serviceName,
string? serviceDescription
)
{
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = serviceName,
Description = serviceDescription,
TermsOfService = new Uri("https://solsynth.dev/terms"),
License = new OpenApiLicense
{
Name = "APGLv3",
Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.html")
}
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Solar Network Unified Authentication",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
[]
}
});
});
builder.Services.AddOpenApi();
return builder;
}
public static WebApplication UseSwaggerManifest(this WebApplication app)
{
app.MapOpenApi();
var configuration = app.Configuration;
app.UseSwagger(c =>
{
c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
{
var publicBasePath = configuration["Swagger:PublicBasePath"]?.TrimEnd('/') ?? "";
// 1. Adjust servers
swaggerDoc.Servers = new List<OpenApiServer>
{
new() { Url = publicBasePath }
};
// 2. Rewrite all path keys (remove /api or replace it)
var newPaths = new OpenApiPaths();
foreach (var (path, pathItem) in swaggerDoc.Paths)
{
// e.g. original path = "/api/drive/chunk/{taskId}/{chunkIndex}"
// We want to produce "/sphere/drive/chunk/{taskId}/{chunkIndex}" or maybe "/sphere/chunk/..."
var newPathKey = path;
// If "path" starts with "/api", strip it
if (newPathKey.StartsWith("/api", StringComparison.OrdinalIgnoreCase))
{
newPathKey = newPathKey["/api".Length..];
if (!newPathKey.StartsWith("/"))
newPathKey = "/" + newPathKey;
}
// Then prepend the public base path (if not root)
if (!string.IsNullOrEmpty(publicBasePath) && publicBasePath != "/")
{
// ensure slash composition
newPathKey = publicBasePath.TrimEnd('/') + newPathKey;
}
newPaths.Add(newPathKey, pathItem);
}
swaggerDoc.Paths = newPaths;
});
});
app.UseSwaggerUI(options =>
{
// Swagger UI must point to the JSON location
var publicBasePath = configuration["Swagger:PublicBasePath"]?.TrimEnd('/') ?? "";
options.SwaggerEndpoint(
$"{publicBasePath}/swagger/v1/swagger.json",
"Develop API v1");
});
return app;
}
}

View File

@@ -56,9 +56,9 @@
<PackageReference Include="Quartz.AspNetCore" Version="3.14.0"/> <PackageReference Include="Quartz.AspNetCore" Version="3.14.0"/>
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.14.0"/> <PackageReference Include="Quartz.Extensions.Hosting" Version="3.14.0"/>
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="11.0.0"/> <PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="11.0.0"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3"/> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="9.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3"/> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.4" />
<PackageReference Include="System.ServiceModel.Syndication" Version="9.0.7" /> <PackageReference Include="System.ServiceModel.Syndication" Version="9.0.7" />
<PackageReference Include="TencentCloudSDK.Tmt" Version="3.0.1276" /> <PackageReference Include="TencentCloudSDK.Tmt" Version="3.0.1276" />
</ItemGroup> </ItemGroup>

View File

@@ -17,21 +17,20 @@ builder.ConfigureAppKestrel(builder.Configuration);
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting(); builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(); builder.Services.AddDysonAuth();
builder.Services.AddAccountService(); builder.Services.AddAccountService();
builder.Services.AddRingService(); builder.Services.AddRingService();
builder.Services.AddDriveService(); builder.Services.AddDriveService();
// Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();
// Add business services
builder.Services.AddAppBusinessServices(builder.Configuration); builder.Services.AddAppBusinessServices(builder.Configuration);
// Add scheduled jobs
builder.Services.AddAppScheduledJobs(); builder.Services.AddAppScheduledJobs();
builder.AddSwaggerManifest(
"DysonNetwork.Sphere",
"The social network service in the Solar Network."
);
var app = builder.Build(); var app = builder.Build();
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
@@ -46,4 +45,6 @@ using (var scope = app.Services.CreateScope())
// Configure application middleware pipeline // Configure application middleware pipeline
app.ConfigureAppMiddleware(builder.Configuration); app.ConfigureAppMiddleware(builder.Configuration);
app.UseSwaggerManifest();
app.Run(); app.Run();

View File

@@ -1,7 +1,6 @@
using DysonNetwork.Shared.Auth; using DysonNetwork.Shared.Auth;
using DysonNetwork.Shared.Http; using DysonNetwork.Shared.Http;
using DysonNetwork.Sphere.Publisher; using DysonNetwork.Sphere.Publisher;
using Prometheus;
namespace DysonNetwork.Sphere.Startup; namespace DysonNetwork.Sphere.Startup;
@@ -9,12 +8,6 @@ public static class ApplicationConfiguration
{ {
public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration) public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration)
{ {
app.MapMetrics();
app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
app.UseRequestLocalization(); app.UseRequestLocalization();
app.ConfigureForwardedHeaders(configuration); app.ConfigureForwardedHeaders(configuration);

View File

@@ -90,55 +90,7 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddAppAuthentication(this IServiceCollection services) public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
{ {
services.AddCors();
services.AddAuthorization(); services.AddAuthorization();
return services;
}
public static IServiceCollection AddAppSwagger(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Solar Network API",
Description = "An open-source social network",
TermsOfService = new Uri("https://solsynth.dev/terms"),
License = new OpenApiLicense
{
Name = "APGLv3",
Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.html")
}
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
[]
}
});
});
services.AddOpenApi();
return services; return services;
} }

View File

@@ -114,6 +114,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObjectArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F5a4ac5580901145fbbc344acc1bf191ccbbf7d8064f6344b677dcf5e1b_003FObjectArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObjectArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F5a4ac5580901145fbbc344acc1bf191ccbbf7d8064f6344b677dcf5e1b_003FObjectArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe6898c1ddf974e16b95b114722270029e55000_003F8e_003F98039498_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe6898c1ddf974e16b95b114722270029e55000_003F8e_003F98039498_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOk_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003F3b_003F237bf104_003FOk_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOk_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F01d30b32e2ff422cb80129ca2a441c4242600_003F3b_003F237bf104_003FOk_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOpenApiInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Ffcedb617b237dc31e998d31e01f101e8441948433938518c5f20cec1a845c1_003FOpenApiInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOptionsConfigurationServiceCollectionExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6622dea924b14dc7aa3ee69d7c84e5735000_003Fe0_003F024ba0b7_003FOptionsConfigurationServiceCollectionExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOptionsConfigurationServiceCollectionExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6622dea924b14dc7aa3ee69d7c84e5735000_003Fe0_003F024ba0b7_003FOptionsConfigurationServiceCollectionExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APathStringTransform_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003Fc5_003Fc4220f9f_003FPathStringTransform_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APathStringTransform_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003Fc5_003Fc4220f9f_003FPathStringTransform_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APathTransformExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003Fd9_003Faff65774_003FPathTransformExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APathTransformExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003Fd9_003Faff65774_003FPathTransformExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>