diff --git a/dotnet/AipsCore/Domain/Models/User/External/UserRole.cs b/dotnet/AipsCore/Domain/Models/User/External/UserRole.cs new file mode 100644 index 0000000..de0a13e --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/User/External/UserRole.cs @@ -0,0 +1,26 @@ +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.Validation; + +namespace AipsCore.Domain.Models.User.External; + +public record UserRole +{ + public string Name { get; init; } + + private UserRole(string Name) + { + this.Name = Name; + } + + public static UserRole User => new("User"); + public static UserRole Admin => new("Admin"); + + public static IEnumerable All() => [User, Admin]; + + public static UserRole FromString(string name) + { + var role = All().FirstOrDefault(r => r.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + + return role ?? throw new ValidationException(UserErrors.RoleDoesNotExist(name)); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/User/Validation/UserErrors.cs b/dotnet/AipsCore/Domain/Models/User/Validation/UserErrors.cs index 8f8b122..62affaa 100644 --- a/dotnet/AipsCore/Domain/Models/User/Validation/UserErrors.cs +++ b/dotnet/AipsCore/Domain/Models/User/Validation/UserErrors.cs @@ -1,5 +1,6 @@ using AipsCore.Domain.Abstract.Validation; using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.External; using AipsCore.Domain.Models.User.ValueObjects; namespace AipsCore.Domain.Models.User.Validation; @@ -21,4 +22,12 @@ public class UserErrors : AbstractErrors return CreateValidationError(code, message); } + + public static ValidationError RoleDoesNotExist(string name) + { + string code = "user_role_does_not_exist"; + string message = $"Role '{name}' does not exist"; + + return CreateValidationError(code, message); + } } \ No newline at end of file diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Db/DbInitializer.cs b/dotnet/AipsCore/Infrastructure/Persistence/Db/DbInitializer.cs new file mode 100644 index 0000000..81edaf3 --- /dev/null +++ b/dotnet/AipsCore/Infrastructure/Persistence/Db/DbInitializer.cs @@ -0,0 +1,29 @@ +using AipsCore.Domain.Models.User.External; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.DependencyInjection; + +namespace AipsCore.Infrastructure.Persistence.Db; + +public static class DbInitializer +{ + public static async Task SeedRolesAsync(IServiceProvider serviceProvider) + { + using var scope = serviceProvider.CreateScope(); + var roleManager = scope.ServiceProvider.GetRequiredService>>(); + + var roleNames = UserRole.All(); + + foreach (var roleName in roleNames) + { + var roleExist = await roleManager.RoleExistsAsync(roleName.Name); + if (!roleExist) + { + await roleManager.CreateAsync(new IdentityRole + { + Name = roleName.Name, + NormalizedName = roleName.Name.ToUpperInvariant() + }); + } + } + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Infrastructure/Persistence/User/UserRepository.cs b/dotnet/AipsCore/Infrastructure/Persistence/User/UserRepository.cs index e4f6965..525a36d 100644 --- a/dotnet/AipsCore/Infrastructure/Persistence/User/UserRepository.cs +++ b/dotnet/AipsCore/Infrastructure/Persistence/User/UserRepository.cs @@ -65,8 +65,7 @@ public class UserRepository : AbstractRepository LoginWithEmailAndPasswordAsync(string email, string password, CancellationToken cancellationToken = default) diff --git a/dotnet/AipsWebApi/Program.cs b/dotnet/AipsWebApi/Program.cs index 9c75565..42ebe7c 100644 --- a/dotnet/AipsWebApi/Program.cs +++ b/dotnet/AipsWebApi/Program.cs @@ -1,4 +1,5 @@ using AipsCore.Infrastructure.DI; +using AipsCore.Infrastructure.Persistence.Db; using AipsWebApi.Middleware; using DotNetEnv; @@ -15,13 +16,17 @@ builder.Services.AddAips(builder.Configuration); var app = builder.Build(); +using (var scope = app.Services.CreateScope()) +{ + await DbInitializer.SeedRolesAsync(scope.ServiceProvider); +} + // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } - app.UseMiddleware(); app.UseAuthentication();