using AutoMapper; using Wishlist.Areas.Identity; using Wishlist.Data; using Wishlist.Models; using Wishlist.Services; using Wishlist.ViewModels; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using FluentMigrator.Runner; using Wishlist.Data.DB.Migrations; using Wishlist.Data.DB; internal class Program { private static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(options => options.UseInMemoryDatabase("ConnectionInMemory") ); builder.Services.Configure(options => { // Default Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = false; // Default Password settings. options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 0; // Default SignIn settings. options.SignIn.RequireConfirmedAccount = false; options.SignIn.RequireConfirmedEmail = false; options.SignIn.RequireConfirmedPhoneNumber = false; // Default User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = true; }); builder.Services.ConfigureApplicationCookie(options => { options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.Cookie.Name = "BlazorAppAuth"; options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.LoginPath = "/Identity/Account/Login"; // ReturnUrlParameter requires //using Microsoft.AspNetCore.Authentication.Cookies; options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; options.SlidingExpiration = true; }); builder.Services.Configure(option => { option.IterationCount = 12000; }); builder.Services.AddIdentity() .AddSignInManager>() .AddUserManager>() .AddRoles() .AddRoleManager>() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); builder.Services.AddAutoMapper(typeof(Program)); builder.Services.AddScoped>(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddAuthorization(opts => { opts.AddPolicy(ProjectPolicies.BlogPostCreateClaimPolicy.Name, policy => { foreach (var claim in ProjectPolicies.BlogPostCreateClaimPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.BlogPostReadClaimPolicy.Name, policy => { foreach (var claim in ProjectPolicies.BlogPostReadClaimPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.BlogPostUpdateClaimPolicy.Name, policy => { foreach (var claim in ProjectPolicies.BlogPostUpdateClaimPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.BlogPostDeleteClaimPolicy.Name, policy => { foreach (var claim in ProjectPolicies.BlogPostDeleteClaimPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.WishlistViewPolicy.Name, policy => { foreach (var claim in ProjectPolicies.WishlistViewPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.WishlistCreatePolicy.Name, policy => { foreach (var claim in ProjectPolicies.WishlistCreatePolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); opts.AddPolicy(ProjectPolicies.WishlistMarkAsBuyingPolicy.Name, policy => { foreach (var claim in ProjectPolicies.WishlistMarkAsBuyingPolicy.RequiredClaims) policy.RequireClaim(claim.Type, [claim.Value]); }); }); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); var mapperConfiguration = new MapperConfiguration(configuration => { var profile = new MappingProfile(); configuration.AddProfile(profile); }); var mapper = mapperConfiguration.CreateMapper(); builder.Services.AddSingleton(mapper); builder.Services.AddScoped(); // add external logins var config = builder.Configuration; builder.Services.AddAuthentication() .AddGoogle(options => { IConfigurationSection googleAuthSection = config.GetSection("Authentication:Google"); options.ClientId = googleAuthSection["ClientId"]; options.ClientSecret = googleAuthSection["ClientSecret"]; }) .AddFacebook(options => { IConfigurationSection facebookAuthSection = config.GetSection("Authentication:Facebook"); options.ClientId = facebookAuthSection["ClientId"]; options.ClientSecret = facebookAuthSection["ClientSecret"]; options.Scope.Add("email"); options.Scope.Add("public_profile"); }) .AddMicrosoftAccount(microsoftOptions => { IConfigurationSection microsoftAuthSection = config.GetSection("Authentication:Microsoft"); microsoftOptions.ClientId = microsoftAuthSection["ClientId"]; microsoftOptions.ClientSecret = microsoftAuthSection["ClientSecret"]; }); //.AddTwitter(twitterOptions => //{ // IConfigurationSection twitterAuthSection = config.GetSection("Authentication:Twitter"); // twitterOptions.ConsumerKey = twitterAuthSection["ConsumerAPIKey"]; // twitterOptions.ConsumerSecret = twitterAuthSection["ConsumerSecret"]; // twitterOptions.RetrieveUserDetails = true; //}); builder.Services .AddFluentMigratorCore() .ConfigureRunner(rb => rb .AddSqlServer() .WithGlobalConnectionString(config.GetConnectionString("main")) .ScanIn(typeof(_20240630_2015_InitialTables).Assembly).For.Migrations()); var app = builder.Build(); // add seed data to inmemory database builder.Services.CreateDatabase().GetAwaiter().GetResult(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Services.GetRequiredService().MigrateUp(); app.Run(); } } public static class ServiceCollectionExtensitions { public static async Task CreateDatabase(this IServiceCollection services) { using (IServiceScope tmp = services.BuildServiceProvider().CreateScope()) { await using var _context = tmp.ServiceProvider.GetRequiredService(); var seedData = tmp.ServiceProvider.GetRequiredService(); await seedData.CreateInitialData(); } } } public class MappingProfile : Profile { public MappingProfile() { CreateMap().ReverseMap(); CreateMap().ReverseMap(); } }