aboutsummaryrefslogtreecommitdiff
path: root/ExamTemplate
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2021-05-06 21:52:47 +0300
committerSyndamia <kamen.d.mladenov@protonmail.com>2021-05-06 21:52:47 +0300
commit57cc5682a0efe2b790015f77fe9d2e2a0bb6ed87 (patch)
treef11fbf515f431db7961bf012d3d2d6a0ac050fbe /ExamTemplate
parent92c4a9a5bcfa543740d2a3e2a9682205fed7ab0b (diff)
downloadit-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
Diffstat (limited to 'ExamTemplate')
-rw-r--r--ExamTemplate/Data/Models/Role.cs3
-rw-r--r--ExamTemplate/Data/Models/User.cs2
-rw-r--r--ExamTemplate/Data/Repositories/UserRepository.cs40
-rw-r--r--ExamTemplate/Services/Configurations/UserMappings.cs14
-rw-r--r--ExamTemplate/Services/Models/RegisterUserServiceModel.cs10
-rw-r--r--ExamTemplate/Services/Services.csproj4
-rw-r--r--ExamTemplate/Services/UserService.cs30
-rw-r--r--ExamTemplate/Web/Configurations/UserMappings.cs14
-rw-r--r--ExamTemplate/Web/Controllers/HomeController.cs2
-rw-r--r--ExamTemplate/Web/Controllers/UserController.cs42
-rw-r--r--ExamTemplate/Web/Models/User/RegisterUserViewModel.cs10
-rw-r--r--ExamTemplate/Web/Startup.cs47
-rw-r--r--ExamTemplate/Web/Views/User/Register.cshtml12
-rw-r--r--ExamTemplate/Web/Web.csproj2
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>