Autho fix

This commit is contained in:
Vitaliy 2024-06-19 21:31:25 +03:00
parent 1dcb66b08d
commit f29c3d19dd
9 changed files with 109 additions and 42 deletions

View File

@ -4,16 +4,19 @@ using Microsoft.EntityFrameworkCore;
namespace HackathonPreparing.ApiService.AuthFeature.EfCore;
public class UserContext : IdentityDbContext<AuthFeature.User, IdentityRole<int>, int>
public class UserContext : IdentityDbContext<User, IdentityRole<int>, int>
{
public UserContext (DbContextOptions<UserContext> options) : base(options) {}
public UserContext (DbContextOptions<UserContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(typeof(Program).Assembly);
builder.HasDefaultSchema("user");
builder.ApplyConfigurationsFromAssembly(typeof(Program).Assembly);
}
}

View File

@ -2,6 +2,8 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Swashbuckle.AspNetCore.SwaggerGen;
using static HackathonPreparing.ApiService.Features.DevFeature.ReflectionHelpers;
namespace HackathonPreparing.ApiService.DevFeature;
@ -9,21 +11,15 @@ public static class DbHelpersEndpointsExtensions
{
public static RouteGroupBuilder AddDbHelpersEndpoints(this WebApplication app)
{
var group = app.MapGroup("/db");
var group = app.MapGroup("db");
group.MapPost("/migrate/{contexClassName}", async (string contexClasstName, IServiceProvider services) =>
{
var contextType = typeof(Program).Assembly.GetType(contexClasstName);
var contextType = GetEfCoreClassContexts().FirstOrDefault(c => c.Name == contexClasstName);
if(contextType is null)
return Results.NotFound();
var inheritanceChain = contextType.GetInheritanceChain();
if(!inheritanceChain.Any(t => typeof(DbContext) == t))
return Results.NotFound();
using var scope = services.CreateScope();
var dbContext = (DbContext)scope.ServiceProvider.GetRequiredService(contextType);
@ -34,17 +30,11 @@ public static class DbHelpersEndpointsExtensions
group.MapPost("/initdb/{contexClassName}", async (string contexClasstName, IServiceProvider services) =>
{
var contextType = typeof(Program).Assembly.GetType(contexClasstName);
var contextType = GetEfCoreClassContexts().FirstOrDefault(c => c.Name == contexClasstName);
if(contextType is null)
return Results.NotFound();
var inheritanceChain = contextType.GetInheritanceChain();
if(!inheritanceChain.Any(t => typeof(DbContext) == t))
return Results.NotFound();
using var scope = services.CreateScope();
var dbContext = (DbContext)scope.ServiceProvider.GetRequiredService(contextType);
@ -53,6 +43,33 @@ public static class DbHelpersEndpointsExtensions
return Results.Ok();
});
group.MapPost("/initdb", async (IServiceProvider services) =>
{
foreach(var contextType in GetEfCoreClassContexts())
{
using var scope = services.CreateScope();
var dbContext = (DbContext)scope.ServiceProvider.GetRequiredService(contextType);
await dbContext.Database.EnsureCreatedAsync();
}
return Results.Ok();
});
group.MapPost("/migrate", async (IServiceProvider services) =>
{
foreach(var contextType in GetEfCoreClassContexts())
{
using var scope = services.CreateScope();
var dbContext = (DbContext)scope.ServiceProvider.GetRequiredService(contextType);
await dbContext.Database.MigrateAsync();
}
return Results.Ok();
});
group.MapPost("/add-moderator", async ([FromServices]UserManager<AuthFeature.User> userManager) => {
var user = new AuthFeature.User{
Email = "m@gmail.com",

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace HackathonPreparing.ApiService.Features.DevFeature;
public static class ReflectionHelpers
{
private static IEnumerable<Type>? EfCoreDbContexts;
// !!!!
// DONT USE FOR HIGH CONCURANCY TASKS
// IT NOT FOR MULTITHREADING CODE
// OF FOR MANY REQUESTS PER MINUTE
// !!!!
public static IEnumerable<Type> GetEfCoreClassContexts()
{
if(EfCoreDbContexts is null)
{
//Get all types with DbContext parent type
EfCoreDbContexts = typeof(Program).Assembly.GetTypes().Where(t =>
t.GetInheritanceChain().Any(inheritanType =>
inheritanType.Name is not null && inheritanType.Name == nameof(DbContext)));
}
return EfCoreDbContexts;
}
}

View File

@ -12,4 +12,13 @@ public static class ServicesExtensions
optionsBuilder => optionsBuilder.UseNpgsql(npgsqlBuilder =>
npgsqlBuilder.MigrationsAssembly(typeof(Program).Assembly.GetName().Name)));
}
// public static void AddDbContextWithDefaultConfiguration<TDbContext>(this WebApplicationBuilder builder) where TDbContext : DbContext
// {
// var connection = builder.Configuration.GetConnectionString("prod") ?? throw new NullReferenceException("CONNECTION TO POSTGRES IS NULL");
// builder.Services.AddDbContext<TDbContext>(b => b.UseNpgsql(connection, npgsqlBuilder =>
// npgsqlBuilder.MigrationsAssembly(typeof(Program).Assembly.GetName().Name)));
// }
}

View File

@ -10,12 +10,12 @@ public sealed class WeatherForecastContext : DbContext
}
public DbSet<WeatherForecast> Forecasts => Set<ApiService.WeatherForecastFeature.WeatherForecast>();
public DbSet<WeatherForecast> Forecasts => Set<WeatherForecast>();
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(typeof(Program).Assembly);
builder.HasDefaultSchema("weatherforecast");
builder.ApplyConfigurationsFromAssembly(typeof(Program).Assembly);
}
}

View File

@ -1,5 +1,6 @@
using HackathonPreparing.ApiService.WeatherForecastFeature.EfCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
namespace HackathonPreparing.ApiService.WeatherForecastFeature;
@ -7,9 +8,9 @@ public static class WeatherForecastEndpointsExtensions
{
public static void AddWeatherForecastEndpoints (this WebApplication app)
{
var group = app.MapGroup("/weatherforecast");
group.MapGet("/", async (WeatherForecastContext db) => await db.Forecasts.ToListAsync());
group.MapDelete("/{id}", async (WeatherForecastContext db, int id) =>
var group = app.MapGroup("weatherforecast");
group.MapGet(string.Empty, async (WeatherForecastContext db) => await db.Forecasts.ToListAsync());
group.MapDelete("{id}", [Authorize(Roles="moderator")]async (WeatherForecastContext db, int id) =>
{
var forecast = await db.Forecasts.FindAsync(id);
if (forecast == null)
@ -21,15 +22,15 @@ public static class WeatherForecastEndpointsExtensions
await db.SaveChangesAsync();
return Results.NoContent();
}).RequireAuthorization("moderator");
group.MapPost("/", async (WeatherForecastContext db, ApiService.WeatherForecastFeature.WeatherForecast forecast) =>
});
group.MapPost(string.Empty, [Authorize(Roles="moderator")] async (WeatherForecastContext db, WeatherForecast forecast) =>
{
db.Forecasts.Add(forecast);
await db.SaveChangesAsync();
return Results.Created($"/weatherforecast/{forecast.Id}", forecast);
});
group.MapPut("/{id}", async (WeatherForecastContext db, int id, ApiService.WeatherForecastFeature.WeatherForecast forecast) =>
group.MapPut("{id}", [Authorize(Roles="moderator")] async (WeatherForecastContext db, int id, WeatherForecast forecast) =>
{
if (id != forecast.Id)
{
@ -53,7 +54,7 @@ public static class WeatherForecastEndpointsExtensions
}
return Results.NoContent();
}).RequireAuthorization("moderator");
});
group.WithTags("weatherforecast");
}
}

View File

@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6">

View File

@ -4,7 +4,6 @@ using HackathonPreparing.ApiService.DevFeature;
using HackathonPreparing.ApiService.WeatherForecastFeature;
using HackathonPreparing.ApiService.WeatherForecastFeature.EfCore;
using HackathonPreparing.ServiceDefaults;
using Microsoft.AspNetCore.Identity;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
@ -43,16 +42,12 @@ builder.Services.AddSwaggerGen(c =>
builder.Services.AddAuthorization();
builder.Services.AddAuthorizationBuilder()
.AddPolicy("moderator", policy =>
policy.RequireRole("MODERATOR"));
//TODO BEARER
builder.Services.AddAuthentication().AddBearerToken(IdentityConstants.BearerScheme);
builder.Services.AddAuthentication().AddBearerToken();
builder.Services.AddIdentity<User, IdentityRole<int>>()
.AddEntityFrameworkStores<UserContext>()
.AddApiEndpoints();
builder.Services
.AddIdentityApiEndpoints<User>()
.AddEntityFrameworkStores<UserContext>();
// Add services to the container.
builder.Services.AddProblemDetails();
@ -62,7 +57,12 @@ builder.AddDbContextWithDefaultConfiguration<UserContext>();
var app = builder.Build();
app.UsePathBase(new PathString("/api"));
app.UsePathBase("/api");
app.UseRouting();
app.MapGet("/test", () => {});
if (app.Environment.IsDevelopment())
{
@ -73,16 +73,21 @@ if (app.Environment.IsDevelopment())
app.AddDbHelpersEndpoints();
}
//Configure the HTTP request pipeline.
app.UseExceptionHandler();
app.UseAuthorization();
app.UseAuthentication();
app.UseAuthorization();
app.AddWeatherForecastEndpoints();
app.MapDefaultEndpoints();
app.MapGroup("/user")
app.MapGroup("user")
.MapIdentityApi<User>()
.WithTags("user");

View File

@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"ConnectionStrings": {
"prod": "User ID=postgres;Password=postgres;Host=localhost;Port=5432;Database=prod;"
}
}