yavsc/src/Yavsc.Blogs/Program.cs
Paul Schneider 006e05a375 fix(blogs): register controller endpoints via MapControllers
All [ApiController] classes (BlogApi, BlogTags, PostTags, FileSystem,
FileSystemStream, Comments, TagsApi) returned 404 on every route,
even though Kestrel was up. The pipeline in Program.cs was missing
MapControllers(), so the controllers were never attached to the
endpoint data source. MapIdentityApi and MapGet("/identity")
worked because they're explicit minimal-API routes; the attribute-
routed controllers didn't.

Confirmed end-to-end: GET /api/v1/blog now returns 401 (auth
required by [Authorize("BlogScope")]) instead of 404.
2026-07-07 21:48:02 +01:00

103 lines
3.3 KiB
C#

using IdentityModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Yavsc;
using Yavsc.Interface;
using Yavsc.Interfaces;
using Yavsc.Models;
using Yavsc.Services;
using Yavsc.Server.Helpers;
using Microsoft.AspNetCore.Identity;
namespace Yavsc.Blogs;
internal class Program
{
private static async Task Main(string[] args)
{
Console.Title = "Yavsc.Blogs";
var builder = WebApplication.CreateBuilder(args);
builder.AddConfiguration("blogs");
var services = builder.Services;
// MvcBuilder
builder.Services
.AddAuthorization(options =>
{
options.AddPolicy("BlogScope", policy =>
{
policy
.RequireAuthenticatedUser()
.RequireClaim(JwtClaimTypes.Scope, new string[] { "blogs" });
});
})
.AddYavscCors(builder.Configuration)
.AddControllers();
// AuthenticationBuilder
services.AddAuthentication("Bearer")
.AddYavscJwtBearer(builder.Configuration);
// DbContextBuilder
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString(
YavscConstants.YavscConnectionStringName)));
// other services
services
.AddTransient<ITrueEmailSender, MailSender>()
.AddTransient<IEmailSender<ApplicationUser>, MailSender>()
.TryAddSingleton<ISmtpClientFactory, SmtpClientFactory>();
services
.AddTransient<IBillingService, BillingService>()
.AddTransient<ICalendarManager, CalendarManager>()
.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>()
.AddTransient<BlogSpotService>()
.AddScoped<IAuthorizationHandler, PermissionHandler>()
.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
})
.AddDistributedMemoryCache()
.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = false;
}).Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[] { "fr", "en", "pt" };
options.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
});
// App startup
using (var app = builder.Build())
{
if (app.Environment.IsDevelopment())
app.UseDeveloperExceptionPage();
app
.UseRouting()
.UseAuthentication()
.UseAuthorization()
.UseCors("default")
;
app.MapControllers();
app.MapIdentityApi<ApplicationUser>().RequireAuthorization("BlogScope");
app.MapGet("/identity", (HttpContext context) =>
new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))
);
app.UseSession();
await app.RunAsync();
}
}
}