2024-01-11 12:54:29 +00:00
|
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
2024-01-16 12:52:24 +00:00
|
|
|
using Microsoft.AspNetCore.Components.Forms;
|
2024-01-11 12:54:29 +00:00
|
|
|
using Microsoft.AspNetCore.Components.Server;
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
using Wave.Components;
|
|
|
|
using Wave.Components.Account;
|
|
|
|
using Wave.Data;
|
2024-01-13 14:18:17 +00:00
|
|
|
using Wave.Services;
|
2024-01-11 12:54:29 +00:00
|
|
|
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
2024-01-13 12:43:19 +00:00
|
|
|
builder.Configuration.AddEnvironmentVariables("WAVE_");
|
2024-01-11 12:54:29 +00:00
|
|
|
|
2024-01-13 14:18:17 +00:00
|
|
|
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
|
|
|
|
builder.Services.AddControllers();
|
2024-01-11 12:54:29 +00:00
|
|
|
|
2024-01-11 14:39:09 +00:00
|
|
|
#region Authentication & Authorization
|
|
|
|
|
2024-01-11 12:54:29 +00:00
|
|
|
builder.Services.AddCascadingAuthenticationState();
|
|
|
|
builder.Services.AddScoped<IdentityUserAccessor>();
|
|
|
|
builder.Services.AddScoped<IdentityRedirectManager>();
|
|
|
|
builder.Services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
|
|
|
|
|
2024-01-16 12:52:24 +00:00
|
|
|
// Authors: Can create Articles, require them to be reviewed
|
|
|
|
// Reviewers: Can review Articles, but cannot create them themselves
|
|
|
|
// Moderators: Can delete Articles / take them Offline
|
|
|
|
// Admins: Can do anything, and assign roles to other users
|
|
|
|
builder.Services.AddAuthorizationBuilder()
|
|
|
|
.AddPolicy("ArticleEditPermissions", p => p.RequireRole("Author", "Admin"))
|
|
|
|
.AddPolicy("ArticleReviewPermissions", p => p.RequireRole("Reviewer", "Admin"))
|
|
|
|
.AddPolicy("ArticleDeletePermissions", p => p.RequireRole("Moderator", "Admin"))
|
|
|
|
.AddPolicy("RoleAssignPermissions", p => p.RequireRole("Admin"));
|
|
|
|
builder.Services.AddAuthentication(options => {
|
2024-01-11 12:54:29 +00:00
|
|
|
options.DefaultScheme = IdentityConstants.ApplicationScheme;
|
|
|
|
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
|
2024-01-16 12:52:24 +00:00
|
|
|
}).AddIdentityCookies();
|
2024-01-11 12:54:29 +00:00
|
|
|
|
2024-01-11 14:39:09 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Identity
|
|
|
|
|
2024-01-13 12:43:19 +00:00
|
|
|
string connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
|
|
|
|
?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
|
2024-01-14 18:04:06 +00:00
|
|
|
builder.Services.AddDbContextFactory<ApplicationDbContext>(options =>
|
2024-01-13 12:43:19 +00:00
|
|
|
options.UseNpgsql(connectionString));
|
2024-01-11 12:54:29 +00:00
|
|
|
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
|
|
|
|
|
|
|
builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
|
|
|
|
.AddEntityFrameworkStores<ApplicationDbContext>()
|
|
|
|
.AddSignInManager()
|
|
|
|
.AddDefaultTokenProviders();
|
|
|
|
|
|
|
|
builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
|
|
|
|
|
2024-01-11 14:39:09 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Services
|
|
|
|
|
|
|
|
builder.Services.AddLocalization(options => {
|
|
|
|
options.ResourcesPath = "Resources";
|
|
|
|
});
|
2024-01-13 14:18:17 +00:00
|
|
|
builder.Services.AddScoped<ImageService>();
|
2024-01-11 14:39:09 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2024-01-11 12:54:29 +00:00
|
|
|
var app = builder.Build();
|
|
|
|
|
|
|
|
// Configure the HTTP request pipeline.
|
2024-01-11 14:39:09 +00:00
|
|
|
if (app.Environment.IsDevelopment()) {
|
2024-01-11 12:54:29 +00:00
|
|
|
app.UseMigrationsEndPoint();
|
2024-01-11 14:39:09 +00:00
|
|
|
} else {
|
2024-01-11 12:54:29 +00:00
|
|
|
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
|
|
|
}
|
|
|
|
|
|
|
|
app.UseStaticFiles();
|
|
|
|
app.UseAntiforgery();
|
|
|
|
|
2024-01-13 14:18:17 +00:00
|
|
|
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
|
2024-01-11 12:54:29 +00:00
|
|
|
|
|
|
|
// Add additional endpoints required by the Identity /Account Razor components.
|
|
|
|
app.MapAdditionalIdentityEndpoints();
|
|
|
|
|
2024-01-13 14:18:17 +00:00
|
|
|
app.MapControllers();
|
|
|
|
|
2024-01-11 14:39:09 +00:00
|
|
|
string[] cultures = ["en-US", "en-GB", "de-DE"];
|
|
|
|
app.UseRequestLocalization(new RequestLocalizationOptions {
|
|
|
|
ApplyCurrentCultureToResponseHeaders = true,
|
|
|
|
FallBackToParentCultures = true, FallBackToParentUICultures = true
|
|
|
|
}
|
|
|
|
.SetDefaultCulture(cultures[0])
|
|
|
|
.AddSupportedCultures(cultures)
|
|
|
|
.AddSupportedUICultures(cultures));
|
|
|
|
|
2024-01-15 19:47:10 +00:00
|
|
|
{
|
|
|
|
using var scope = app.Services.CreateScope();
|
|
|
|
using var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
|
|
context.Database.Migrate();
|
|
|
|
}
|
|
|
|
|
2024-01-11 12:54:29 +00:00
|
|
|
app.Run();
|