From b90c9159c4616ad20a0194da31de72fe0dabda24 Mon Sep 17 00:00:00 2001 From: msmahdinejad <154900233+msmahdinejad@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:54:55 +0330 Subject: [PATCH] feat(Migrations): Complete Migrations (#23) * first commit * Add initial data. * Complete & Fix Migrations project. * add permissions. --------- Co-authored-by: sadq --- RelationAnalysis.Migrations/.env.example | 1 - RelationAnalysis.Migrations/ConsoleStartup.cs | 38 --------- .../InitialRecordsCreator.cs | 79 +++++++++++++++++++ RelationAnalysis.Migrations/Program.cs | 44 ++++++++--- .../RelationAnalysis.Migrations.csproj | 9 +++ RelationAnalysis.Migrations/appsettings.json | 3 + RelationshipAnalysis/Dto/CreateUserDto.cs | 2 +- RelationshipAnalysis/Dto/LoginDto.cs | 2 +- .../Dto/UserPasswordInfoDto.cs | 4 +- .../Abstraction/IPasswordHasher.cs | 2 +- .../Abstraction/IPasswordVerifier.cs | 2 +- .../AuthServices/CustomPasswordHasher.cs | 2 +- .../AuthServices/PasswordVerifier.cs | 2 +- RelationshipAnalysis/appsettings.json | 4 + 14 files changed, 137 insertions(+), 57 deletions(-) delete mode 100644 RelationAnalysis.Migrations/.env.example delete mode 100644 RelationAnalysis.Migrations/ConsoleStartup.cs create mode 100644 RelationAnalysis.Migrations/InitialRecordsCreator.cs create mode 100644 RelationAnalysis.Migrations/appsettings.json diff --git a/RelationAnalysis.Migrations/.env.example b/RelationAnalysis.Migrations/.env.example deleted file mode 100644 index 31edd6e..0000000 --- a/RelationAnalysis.Migrations/.env.example +++ /dev/null @@ -1 +0,0 @@ -CONNECTION_STRING="" \ No newline at end of file diff --git a/RelationAnalysis.Migrations/ConsoleStartup.cs b/RelationAnalysis.Migrations/ConsoleStartup.cs deleted file mode 100644 index 01aa7b2..0000000 --- a/RelationAnalysis.Migrations/ConsoleStartup.cs +++ /dev/null @@ -1,38 +0,0 @@ -using DotNetEnv; -using DotNetEnv.Configuration; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using RelationshipAnalysis.Context; -using Microsoft.Extensions.Configuration; - -namespace RelationAnalysis.Migrations -{ - public class ConsoleStartup - { - public IConfiguration Configuration { get; } = new ConfigurationBuilder() - .AddEnvironmentVariables() - .Build(); - public ConsoleStartup() - { - - //.. for test - Console.WriteLine(Configuration["CONNECTION_STRING"]); - } - - public void ConfigureServices(IServiceCollection services) - { - - services.AddDbContext(options => - { - options.UseNpgsql(Configuration["CONNECTION_STRING"]).UseLazyLoadingProxies(); - }); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - - } - } -} \ No newline at end of file diff --git a/RelationAnalysis.Migrations/InitialRecordsCreator.cs b/RelationAnalysis.Migrations/InitialRecordsCreator.cs new file mode 100644 index 0000000..57f88cc --- /dev/null +++ b/RelationAnalysis.Migrations/InitialRecordsCreator.cs @@ -0,0 +1,79 @@ +using Microsoft.Extensions.Configuration; +using RelationshipAnalysis.Context; +using RelationshipAnalysis.Models.Auth; +using RelationshipAnalysis.Services.UserPanelServices.Abstraction.AuthServices; + +namespace RelationAnalysis.Migrations; + +public class InitialRecordsCreator(ApplicationDbContext context, IConfiguration configuration) +{ + public async Task AddInitialRecords() + { + var roles = new List() + { + new Role() + { + Name = "Admin", + Permissions = + "'[\"/api/Access/GetPermissions\",\"/api/Admin/GetUser/{id}\",\"/api/Admin/GetAllUser\",\"/api/Admin/GetAllRoles\",\"/api/Admin/UpdateUser/{id}\",\"/api/Admin/UpdatePassword/{id}\",\"/api/Admin/DeleteUser/{id}\",\"/api/Admin/CreateUser\",\"/api/Admin/UpdateRoles/{id}\",\"/api/Auth/Login\", \"/api/User/GetUser\",\"/api/User/UpdateUser\",\"/api/User/UpdatePassword\",\"/api/User/Logout\"]'", + Id = 1 + }, + new Role() + { + Name = "DataAdmin", + Permissions = + "'[\"/api/Access/GetPermissions\",\"/api/Auth/Login\",\"/api/User/GetUser\",\"/api/User/UpdateUser\",\"/api/User/UpdatePassword\",\"/api/User/Logout\"]'", + Id = 2 + }, + new Role() + { + Name = "DataAnalyst", + Permissions = + "'[\"/api/Access/GetPermissions\",\"/api/Auth/Login\",\"/api/User/GetUser\",\"/api/User/UpdateUser\",\"/api/User/UpdatePassword\",\"/api/User/Logout\"]'", + Id = 3 + } + }; + var userRoles = new List() + { + new UserRole() + { + UserId = 1, + RoleId = 1 + }, + new UserRole() + { + UserId = 1, + RoleId = 2 + }, + new UserRole() + { + UserId = 1, + RoleId = 3 + } + }; + var users = new List() + { + new User() + { + Username = "admin", + PasswordHash = new CustomPasswordHasher() + .HashPassword(configuration.GetValue("DefaultPassword")), + FirstName = "FirstName", + LastName = "LastName", + Email = "admin@gmail.com", + Id = 1, + } + }; + try + { + await context.Roles.AddRangeAsync(roles); + await context.Users.AddRangeAsync(users); + await context.UserRoles.AddRangeAsync(userRoles); + await context.SaveChangesAsync(); + } + catch + { + Console.WriteLine("Data already exists!"); + } + } +} \ No newline at end of file diff --git a/RelationAnalysis.Migrations/Program.cs b/RelationAnalysis.Migrations/Program.cs index 407d10a..798909c 100644 --- a/RelationAnalysis.Migrations/Program.cs +++ b/RelationAnalysis.Migrations/Program.cs @@ -1,24 +1,48 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.EntityFrameworkCore; -using DotNetEnv; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using RelationshipAnalysis.Context; namespace RelationAnalysis.Migrations { class Program { - static void Main(string[] args) + static async Task Main(string[] args) { - Console.WriteLine("Applying migrations"); - var webHost = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseStartup() + Console.WriteLine("Run console app!"); + + + var host = Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((context, config) => + { + config.AddJsonFile("appsettings.json"); + config.AddEnvironmentVariables(); + }) + .ConfigureServices((context, services) => + { + var configuration = context.Configuration; + var connectionString = configuration.GetValue("CONNECTION_STRING"); + + services.AddDbContext(options => + options.UseNpgsql(connectionString)); + + services.AddTransient(); + }) .Build(); - using (var context = (ApplicationDbContext) webHost.Services.GetService(typeof(ApplicationDbContext))) + var configuration = host.Services.GetRequiredService(); + Console.WriteLine(configuration.GetValue("CONNECTION_STRING")); + + using (var scope = host.Services.CreateScope()) { - context.Database.Migrate(); + var dbContext = scope.ServiceProvider.GetRequiredService(); + await dbContext.Database.MigrateAsync(); + + var myService = scope.ServiceProvider.GetRequiredService(); + await myService.AddInitialRecords(); } + Console.WriteLine("Done"); } } diff --git a/RelationAnalysis.Migrations/RelationAnalysis.Migrations.csproj b/RelationAnalysis.Migrations/RelationAnalysis.Migrations.csproj index 6e764ba..4c4adae 100644 --- a/RelationAnalysis.Migrations/RelationAnalysis.Migrations.csproj +++ b/RelationAnalysis.Migrations/RelationAnalysis.Migrations.csproj @@ -10,6 +10,9 @@ + + + @@ -25,4 +28,10 @@ + + + PreserveNewest + + + diff --git a/RelationAnalysis.Migrations/appsettings.json b/RelationAnalysis.Migrations/appsettings.json new file mode 100644 index 0000000..a74fa73 --- /dev/null +++ b/RelationAnalysis.Migrations/appsettings.json @@ -0,0 +1,3 @@ +{ + "DefaultPassword": "admin" +} diff --git a/RelationshipAnalysis/Dto/CreateUserDto.cs b/RelationshipAnalysis/Dto/CreateUserDto.cs index 6dd9afa..5806db6 100644 --- a/RelationshipAnalysis/Dto/CreateUserDto.cs +++ b/RelationshipAnalysis/Dto/CreateUserDto.cs @@ -10,7 +10,7 @@ public class CreateUserDto [Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(Resources))] [RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$", ErrorMessageResourceName = "InvalidPasswordMessage", ErrorMessageResourceType = typeof(Resources))] - public string Password { get; set; } + public string? Password { get; set; } [Required] public string FirstName { get; set; } diff --git a/RelationshipAnalysis/Dto/LoginDto.cs b/RelationshipAnalysis/Dto/LoginDto.cs index 7a734e1..306e1e7 100644 --- a/RelationshipAnalysis/Dto/LoginDto.cs +++ b/RelationshipAnalysis/Dto/LoginDto.cs @@ -6,5 +6,5 @@ public class LoginDto { [Required] public string Username { get; set; } - [Required] public string Password { get; set; } + [Required] public string? Password { get; set; } } \ No newline at end of file diff --git a/RelationshipAnalysis/Dto/UserPasswordInfoDto.cs b/RelationshipAnalysis/Dto/UserPasswordInfoDto.cs index 2530304..2040401 100644 --- a/RelationshipAnalysis/Dto/UserPasswordInfoDto.cs +++ b/RelationshipAnalysis/Dto/UserPasswordInfoDto.cs @@ -5,10 +5,10 @@ namespace RelationshipAnalysis.Dto; public class UserPasswordInfoDto { [Required(ErrorMessageResourceName = "OldPasswordRequired", ErrorMessageResourceType = typeof(Resources))] - public string OldPassword { get; set; } + public string? OldPassword { get; set; } [Required(ErrorMessageResourceName = "NewPasswordRequired", ErrorMessageResourceType = typeof(Resources))] [RegularExpression("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\\W)(?!.* ).{8,}$", ErrorMessageResourceName = "InvalidPasswordMessage", ErrorMessageResourceType = typeof(Resources))] - public string NewPassword { get; set; } + public string? NewPassword { get; set; } } \ No newline at end of file diff --git a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordHasher.cs b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordHasher.cs index 093be4f..c1848e1 100644 --- a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordHasher.cs +++ b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordHasher.cs @@ -2,5 +2,5 @@ public interface IPasswordHasher { - string HashPassword(string input); + string HashPassword(string? input); } \ No newline at end of file diff --git a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordVerifier.cs b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordVerifier.cs index 9b89228..2bc032a 100644 --- a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordVerifier.cs +++ b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/Abstraction/IPasswordVerifier.cs @@ -2,5 +2,5 @@ public interface IPasswordVerifier { - bool VerifyPasswordHash(string password, string storedHash); + bool VerifyPasswordHash(string? password, string storedHash); } \ No newline at end of file diff --git a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/CustomPasswordHasher.cs b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/CustomPasswordHasher.cs index 0195460..98802a1 100644 --- a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/CustomPasswordHasher.cs +++ b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/CustomPasswordHasher.cs @@ -6,7 +6,7 @@ namespace RelationshipAnalysis.Services.UserPanelServices.Abstraction.AuthServic public class CustomPasswordHasher : IPasswordHasher { - public string HashPassword(string input) + public string HashPassword(string? input) { var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(input)); var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); diff --git a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/PasswordVerifier.cs b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/PasswordVerifier.cs index 1db0b08..2d9dd97 100644 --- a/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/PasswordVerifier.cs +++ b/RelationshipAnalysis/Services/UserPanelServices/Abstraction/AuthServices/PasswordVerifier.cs @@ -4,7 +4,7 @@ namespace RelationshipAnalysis.Services.UserPanelServices.Abstraction.AuthServic public class PasswordVerifier(IPasswordHasher passwordHasher) : IPasswordVerifier { - public bool VerifyPasswordHash(string password, string storedHash) + public bool VerifyPasswordHash(string? password, string storedHash) { return passwordHasher.HashPassword(password) == storedHash; } diff --git a/RelationshipAnalysis/appsettings.json b/RelationshipAnalysis/appsettings.json index caf3408..cbc7eab 100644 --- a/RelationshipAnalysis/appsettings.json +++ b/RelationshipAnalysis/appsettings.json @@ -1,4 +1,8 @@ { + "PasswordHash": + { + "DefaultPassword" : "admin" + }, "Jwt": { "CookieName" : "jwt", "Key": "kajbdiuhdqhpjQE89HBSDJIABFCIWSGF89GW3EJFBWEIUBCZNMXCJNLZDKNJKSNJKFBIGW3EASHHDUIASZGCUI",