diff options
| author | Syndamia <kamen.d.mladenov@protonmail.com> | 2021-05-06 21:52:47 +0300 |
|---|---|---|
| committer | Syndamia <kamen.d.mladenov@protonmail.com> | 2021-05-06 21:52:47 +0300 |
| commit | 57cc5682a0efe2b790015f77fe9d2e2a0bb6ed87 (patch) | |
| tree | f11fbf515f431db7961bf012d3d2d6a0ac050fbe | |
| parent | 92c4a9a5bcfa543740d2a3e2a9682205fed7ab0b (diff) | |
| download | it-kariera-exam-template-57cc5682a0efe2b790015f77fe9d2e2a0bb6ed87.tar it-kariera-exam-template-57cc5682a0efe2b790015f77fe9d2e2a0bb6ed87.tar.gz it-kariera-exam-template-57cc5682a0efe2b790015f77fe9d2e2a0bb6ed87.zip | |
Added automapper; Implemented user register; Improved some database configurations
| -rw-r--r-- | ExamTemplate/Data/Models/Role.cs | 3 | ||||
| -rw-r--r-- | ExamTemplate/Data/Models/User.cs | 2 | ||||
| -rw-r--r-- | ExamTemplate/Data/Repositories/UserRepository.cs | 40 | ||||
| -rw-r--r-- | ExamTemplate/Services/Configurations/UserMappings.cs | 14 | ||||
| -rw-r--r-- | ExamTemplate/Services/Models/RegisterUserServiceModel.cs | 10 | ||||
| -rw-r--r-- | ExamTemplate/Services/Services.csproj | 4 | ||||
| -rw-r--r-- | ExamTemplate/Services/UserService.cs | 30 | ||||
| -rw-r--r-- | ExamTemplate/Web/Configurations/UserMappings.cs | 14 | ||||
| -rw-r--r-- | ExamTemplate/Web/Controllers/HomeController.cs | 2 | ||||
| -rw-r--r-- | ExamTemplate/Web/Controllers/UserController.cs | 42 | ||||
| -rw-r--r-- | ExamTemplate/Web/Models/User/RegisterUserViewModel.cs | 10 | ||||
| -rw-r--r-- | ExamTemplate/Web/Startup.cs | 47 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/User/Register.cshtml | 12 | ||||
| -rw-r--r-- | ExamTemplate/Web/Web.csproj | 2 |
14 files changed, 229 insertions, 3 deletions
diff --git a/ExamTemplate/Data/Models/Role.cs b/ExamTemplate/Data/Models/Role.cs index 94e5c48..9a23f13 100644 --- a/ExamTemplate/Data/Models/Role.cs +++ b/ExamTemplate/Data/Models/Role.cs @@ -8,6 +8,9 @@ namespace ExamTemplate.Data.Models [Table("Roles")] public class Role : IdentityRole<Guid> { + public static string UserRole = "User"; + public static string AdminRole = "Administrator"; + public List<User> Users { get; set; } = new List<User>(); } } diff --git a/ExamTemplate/Data/Models/User.cs b/ExamTemplate/Data/Models/User.cs index 0c3f4c7..cb96942 100644 --- a/ExamTemplate/Data/Models/User.cs +++ b/ExamTemplate/Data/Models/User.cs @@ -10,6 +10,6 @@ namespace ExamTemplate.Data.Models { public string FirstName { get; set; } public string LastName { get; set; } - public List<Role> Roles { get; set; } + public List<Role> Roles { get; set; } = new List<Role>(); } } diff --git a/ExamTemplate/Data/Repositories/UserRepository.cs b/ExamTemplate/Data/Repositories/UserRepository.cs new file mode 100644 index 0000000..97eb21b --- /dev/null +++ b/ExamTemplate/Data/Repositories/UserRepository.cs @@ -0,0 +1,40 @@ +using System.Threading.Tasks; +using ExamTemplate.Data.Models; +using Microsoft.AspNetCore.Identity; + +namespace ExamTemplate.Data.Repositories +{ + public class UserRepository + { + private readonly TemplateContext _context; + private readonly UserManager<User> _userManager; + private readonly RoleManager<Role> _roleManager; + + public UserRepository(TemplateContext templateContext, UserManager<User> userManager, RoleManager<Role> roleManager) + { + this._context = templateContext; + this._userManager = userManager; + this._roleManager = roleManager; + } + + public async Task<bool> AddAsync(User user, string password) + { + user.PasswordHash = this._userManager.PasswordHasher.HashPassword(user, password); + IdentityResult result = await this._userManager.CreateAsync(user); + + return result.Succeeded; + } + + public async Task<bool> AddRoleToUserAsync(User user, string roleName) + { + bool succeeded = (await this._userManager.AddToRoleAsync(user, roleName)).Succeeded; + if (succeeded) + { + user.Roles.Add(await this._roleManager.FindByNameAsync(roleName)); + succeeded = await this._context.SaveChangesAsync() >= 1; + } + + return succeeded; + } + } +} diff --git a/ExamTemplate/Services/Configurations/UserMappings.cs b/ExamTemplate/Services/Configurations/UserMappings.cs new file mode 100644 index 0000000..13c6633 --- /dev/null +++ b/ExamTemplate/Services/Configurations/UserMappings.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using ExamTemplate.Data.Models; +using ExamTemplate.Services.Models; + +namespace ExamTemplate.Services.Configurations +{ + public class UserMappings : Profile + { + public UserMappings() + { + CreateMap<RegisterUserServiceModel, User>(); + } + } +} diff --git a/ExamTemplate/Services/Models/RegisterUserServiceModel.cs b/ExamTemplate/Services/Models/RegisterUserServiceModel.cs new file mode 100644 index 0000000..7a274ae --- /dev/null +++ b/ExamTemplate/Services/Models/RegisterUserServiceModel.cs @@ -0,0 +1,10 @@ +namespace ExamTemplate.Services.Models +{ + public class RegisterUserServiceModel + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string Username { get; set; } + public string Password { get; set; } + } +} diff --git a/ExamTemplate/Services/Services.csproj b/ExamTemplate/Services/Services.csproj index 59fa33e..bac932a 100644 --- a/ExamTemplate/Services/Services.csproj +++ b/ExamTemplate/Services/Services.csproj @@ -5,6 +5,10 @@ <ProjectReference Include="..\Common\Common.csproj" /> </ItemGroup>
+ <ItemGroup> + <PackageReference Include="Automapper" Version="10.1.1" /> + </ItemGroup>
+
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
diff --git a/ExamTemplate/Services/UserService.cs b/ExamTemplate/Services/UserService.cs new file mode 100644 index 0000000..848edf6 --- /dev/null +++ b/ExamTemplate/Services/UserService.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks;
+using AutoMapper;
+using ExamTemplate.Data.Models;
+using ExamTemplate.Data.Repositories;
+using ExamTemplate.Services.Models;
+
+namespace ExamTemplate.Services
+{
+ public class UserService
+ {
+ private readonly IMapper _autoMapper;
+ private readonly UserRepository _userRepository;
+
+ public UserService(IMapper autoMapper, UserRepository userRepository)
+ {
+ this._autoMapper = autoMapper;
+ this._userRepository = userRepository;
+ }
+
+ public async Task<bool> RegisterUserAsync(RegisterUserServiceModel registerUserServiceModel)
+ {
+ User user = this._autoMapper.Map<User>(registerUserServiceModel);
+
+ bool userCreateResult = await this._userRepository.AddAsync(user, registerUserServiceModel.Password);
+ bool addRoleResult = await this._userRepository.AddRoleToUserAsync(user, Role.UserRole);
+
+ return userCreateResult && addRoleResult;
+ }
+ }
+}
diff --git a/ExamTemplate/Web/Configurations/UserMappings.cs b/ExamTemplate/Web/Configurations/UserMappings.cs new file mode 100644 index 0000000..d1a5523 --- /dev/null +++ b/ExamTemplate/Web/Configurations/UserMappings.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using ExamTemplate.Services.Models; +using ExamTemplate.Web.Models.User; + +namespace ExamTemplate.Services.Configurations +{ + public class UserMappings : Profile + { + public UserMappings() + { + CreateMap<RegisterUserViewModel, RegisterUserServiceModel>(); + } + } +} diff --git a/ExamTemplate/Web/Controllers/HomeController.cs b/ExamTemplate/Web/Controllers/HomeController.cs index 9f96a95..39ece9a 100644 --- a/ExamTemplate/Web/Controllers/HomeController.cs +++ b/ExamTemplate/Web/Controllers/HomeController.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging;
using Web.Models;
-namespace Web.Controllers
+namespace ExamTemplate.Web.Controllers
{
public class HomeController : Controller
{
diff --git a/ExamTemplate/Web/Controllers/UserController.cs b/ExamTemplate/Web/Controllers/UserController.cs new file mode 100644 index 0000000..cd472de --- /dev/null +++ b/ExamTemplate/Web/Controllers/UserController.cs @@ -0,0 +1,42 @@ +using ExamTemplate.Services; +using Microsoft.AspNetCore.Mvc; +using ExamTemplate.Web.Models.User; +using AutoMapper; +using ExamTemplate.Services.Models; +using System.Threading.Tasks; + +namespace ExamTemplate.Web.Controllers +{ + public class UserController : Controller + { + private readonly IMapper _autoMapper; + private readonly UserService _userService; + + public UserController(IMapper autoMapper, UserService userService) + { + this._autoMapper = autoMapper; + this._userService = userService; + } + + [HttpGet] + [Route("/Register")] + public IActionResult Register() + { + return View(); + } + + [HttpPost] + [Route("/Register")] + public async Task<IActionResult> Register(RegisterUserViewModel registerUserViewModel) + { + RegisterUserServiceModel registerUserServiceModel = this._autoMapper.Map<RegisterUserServiceModel>(registerUserViewModel); + + bool result = await this._userService.RegisterUserAsync(registerUserServiceModel); + + if (result) + return RedirectToAction("Index", "Home"); + else + return View(); + } + } +} diff --git a/ExamTemplate/Web/Models/User/RegisterUserViewModel.cs b/ExamTemplate/Web/Models/User/RegisterUserViewModel.cs new file mode 100644 index 0000000..5764bdd --- /dev/null +++ b/ExamTemplate/Web/Models/User/RegisterUserViewModel.cs @@ -0,0 +1,10 @@ +namespace ExamTemplate.Web.Models.User +{ + public class RegisterUserViewModel + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string Username { get; set; } + public string Password { get; set; } + } +} diff --git a/ExamTemplate/Web/Startup.cs b/ExamTemplate/Web/Startup.cs index e66e40a..9c43601 100644 --- a/ExamTemplate/Web/Startup.cs +++ b/ExamTemplate/Web/Startup.cs @@ -1,6 +1,12 @@ +using System;
+using System.Linq;
using ExamTemplate.Data;
+using ExamTemplate.Data.Models;
+using ExamTemplate.Data.Repositories;
+using ExamTemplate.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -21,10 +27,26 @@ namespace Web public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
+ services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
- // Database configuration
+ /*
+ * Dependency Injection configuration
+ */
+
+ services.AddTransient<UserService>();
+ services.AddTransient<UserRepository>();
+
+ /*
+ * Database configuration
+ */
services.AddDbContext<TemplateContext>(options =>
options.UseNpgsql(this.Configuration.GetConnectionString("LocalDBConnection")));
+
+ // Needed for SignInManager and UserManager
+ services.AddIdentity<User, Role>()
+ .AddRoles<Role>()
+ .AddEntityFrameworkStores<TemplateContext>();
+
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -54,6 +76,29 @@ namespace Web name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
+
+ /*
+ * Make sure that the database is migrated
+ * and that the User and Admin role exist in database
+ */
+
+ using var serviceScope = app.ApplicationServices.CreateScope();
+ using var dbContext = serviceScope.ServiceProvider.GetRequiredService<TemplateContext>();
+
+ dbContext.Database.Migrate();
+
+ var roleManager = (RoleManager<Role>)serviceScope.ServiceProvider.GetService(typeof(RoleManager<Role>));
+ if (!dbContext.Roles.Any(x => x.Name == Role.UserRole))
+ {
+ Role userRole = new() { Name = Role.UserRole };
+ roleManager.CreateAsync(userRole).Wait();
+ }
+ if (!dbContext.Roles.Any(x => x.Name == Role.AdminRole))
+ {
+ Role adminRole = new() { Name = Role.AdminRole };
+ roleManager.CreateAsync(adminRole).Wait();
+ }
+
}
}
}
diff --git a/ExamTemplate/Web/Views/User/Register.cshtml b/ExamTemplate/Web/Views/User/Register.cshtml new file mode 100644 index 0000000..39e39f2 --- /dev/null +++ b/ExamTemplate/Web/Views/User/Register.cshtml @@ -0,0 +1,12 @@ +@model ExamTemplate.Web.Models.User.RegisterUserViewModel +@{ + ViewData["Title"] = "Register"; +} + +<form asp-controller="User" asp-action="Register" method="post"> + <input type="text" asp-for="FirstName" placeholder="FirstName"> + <input type="text" asp-for="LastName" placeholder="LastName"> + <input type="text" asp-for="Username" placeholder="Username"> + <input type="password" asp-for="Password" placeholder="Password"> + <input type="submit"> +</form> diff --git a/ExamTemplate/Web/Web.csproj b/ExamTemplate/Web/Web.csproj index ef3c865..44c6a7a 100644 --- a/ExamTemplate/Web/Web.csproj +++ b/ExamTemplate/Web/Web.csproj @@ -6,6 +6,8 @@ </ItemGroup>
<ItemGroup> + <PackageReference Include="Automapper" Version="10.1.1" /> + <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.5.1" /> </ItemGroup>
|
