diff options
| author | Syndamia <kamen.d.mladenov@protonmail.com> | 2021-05-08 18:10:08 +0300 |
|---|---|---|
| committer | Syndamia <kamen.d.mladenov@protonmail.com> | 2021-05-08 18:10:08 +0300 |
| commit | 82d270a66b8ffca28e321f29b2eb90b2412ac9a7 (patch) | |
| tree | bd7e985592a0d8d5ec31b590b3c52d403e17e140 | |
| parent | a1e46b76a1299e35b1ac8cae69e77c66d74224a6 (diff) | |
| download | it-kariera-exam-template-82d270a66b8ffca28e321f29b2eb90b2412ac9a7.tar it-kariera-exam-template-82d270a66b8ffca28e321f29b2eb90b2412ac9a7.tar.gz it-kariera-exam-template-82d270a66b8ffca28e321f29b2eb90b2412ac9a7.zip | |
Implemented authorization; Replaced Role with IdentityRole<Guid>; Renamed UserController to AccountController, updated links
| -rw-r--r-- | ExamTemplate/Common/RoleConst.cs | 8 | ||||
| -rw-r--r-- | ExamTemplate/Data/Models/Role.cs | 16 | ||||
| -rw-r--r-- | ExamTemplate/Data/Models/User.cs | 1 | ||||
| -rw-r--r-- | ExamTemplate/Data/TemplateContext.cs | 7 | ||||
| -rw-r--r-- | ExamTemplate/Services/UserService.cs | 15 | ||||
| -rw-r--r-- | ExamTemplate/Web/Controllers/AccountController.cs (renamed from ExamTemplate/Web/Controllers/UserController.cs) | 31 | ||||
| -rw-r--r-- | ExamTemplate/Web/Startup.cs | 31 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/Account/Edit.cshtml (renamed from ExamTemplate/Web/Views/User/EditProfile.cshtml) | 0 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/Account/Login.cshtml (renamed from ExamTemplate/Web/Views/User/Login.cshtml) | 2 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/Account/Profile.cshtml (renamed from ExamTemplate/Web/Views/User/Profile.cshtml) | 2 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/Account/Register.cshtml (renamed from ExamTemplate/Web/Views/User/Register.cshtml) | 2 | ||||
| -rw-r--r-- | ExamTemplate/Web/Views/Shared/_Navbar.cshtml | 8 |
12 files changed, 62 insertions, 61 deletions
diff --git a/ExamTemplate/Common/RoleConst.cs b/ExamTemplate/Common/RoleConst.cs new file mode 100644 index 0000000..3f0dfb7 --- /dev/null +++ b/ExamTemplate/Common/RoleConst.cs @@ -0,0 +1,8 @@ +namespace ExamTemplate.Common +{ + public static class RoleConst + { + public static string User = "User"; + public static string Admin = "Administrator"; + } +} diff --git a/ExamTemplate/Data/Models/Role.cs b/ExamTemplate/Data/Models/Role.cs deleted file mode 100644 index 9a23f13..0000000 --- a/ExamTemplate/Data/Models/Role.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Identity; -using System.ComponentModel.DataAnnotations.Schema; - -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 cb96942..e8aecfa 100644 --- a/ExamTemplate/Data/Models/User.cs +++ b/ExamTemplate/Data/Models/User.cs @@ -10,6 +10,5 @@ namespace ExamTemplate.Data.Models { public string FirstName { get; set; } public string LastName { get; set; } - public List<Role> Roles { get; set; } = new List<Role>(); } } diff --git a/ExamTemplate/Data/TemplateContext.cs b/ExamTemplate/Data/TemplateContext.cs index ef675a3..268812d 100644 --- a/ExamTemplate/Data/TemplateContext.cs +++ b/ExamTemplate/Data/TemplateContext.cs @@ -1,11 +1,12 @@ using System;
using ExamTemplate.Data.Models;
+using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace ExamTemplate.Data
{
- public class TemplateContext : IdentityDbContext<User, Role, Guid>
+ public class TemplateContext : IdentityDbContext<User, IdentityRole<Guid>, Guid>
{
public TemplateContext(DbContextOptions<TemplateContext> options)
: base(options) { }
@@ -16,10 +17,6 @@ namespace ExamTemplate.Data .HasIndex(x => x.UserName)
.IsUnique();
- builder.Entity<User>()
- .HasMany(x => x.Roles)
- .WithMany(x => x.Users);
-
base.OnModelCreating(builder);
}
}
diff --git a/ExamTemplate/Services/UserService.cs b/ExamTemplate/Services/UserService.cs index 90a4bf4..e78443a 100644 --- a/ExamTemplate/Services/UserService.cs +++ b/ExamTemplate/Services/UserService.cs @@ -1,4 +1,5 @@ -using System.Security.Claims;
+using System;
+using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using ExamTemplate.Data;
@@ -15,9 +16,9 @@ namespace ExamTemplate.Services private readonly TemplateContext _context;
private readonly SignInManager<User> _signInManager;
private readonly UserManager<User> _userManager;
- private readonly RoleManager<Role> _roleManager;
+ private readonly RoleManager<IdentityRole<Guid>> _roleManager;
- public UserService(IMapper autoMapper, TemplateContext templateContext, SignInManager<User> signInManager, UserManager<User> userManager, RoleManager<Role> roleManager)
+ public UserService(IMapper autoMapper, TemplateContext templateContext, SignInManager<User> signInManager, UserManager<User> userManager, RoleManager<IdentityRole<Guid>> roleManager)
{
this._autoMapper = autoMapper;
this._context = templateContext;
@@ -32,14 +33,9 @@ namespace ExamTemplate.Services user.PasswordHash = this._userManager.PasswordHasher.HashPassword(user, registerUserServiceModel.Password);
IdentityResult userCreateResult = await this._userManager.CreateAsync(user);
-
- // Many to many relationships with Roles can cause problems,
- // that's why I add the Role to the User and add the User to the Role
IdentityResult addRoleResult = await this._userManager.AddToRoleAsync(user, "User");
- user.Roles.Add(await this._roleManager.FindByNameAsync("User"));
- bool roleAddedSuccessfuly = await this._context.SaveChangesAsync() >= 1;
- return userCreateResult.Succeeded && addRoleResult.Succeeded && roleAddedSuccessfuly;
+ return userCreateResult.Succeeded && addRoleResult.Succeeded;
}
public async Task<bool> LoginUserAsync(LoginUserServiceModel loginUserServiceModel)
@@ -57,7 +53,6 @@ namespace ExamTemplate.Services public async Task<UserServiceModel> GetUserByUsernameAsync(string username)
{
User user = await this._userManager.Users
- .Include(x => x.Roles)
.FirstOrDefaultAsync(x => x.UserName == username);
return this._autoMapper.Map<UserServiceModel>(user);
diff --git a/ExamTemplate/Web/Controllers/UserController.cs b/ExamTemplate/Web/Controllers/AccountController.cs index c7183ca..7fb7ab3 100644 --- a/ExamTemplate/Web/Controllers/UserController.cs +++ b/ExamTemplate/Web/Controllers/AccountController.cs @@ -4,29 +4,31 @@ using ExamTemplate.Web.Models.User; using AutoMapper; using ExamTemplate.Services.Models; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; namespace ExamTemplate.Web.Controllers { - public class UserController : Controller + [Authorize] + public class AccountController : Controller { private readonly IMapper _autoMapper; private readonly UserService _userService; - public UserController(IMapper autoMapper, UserService userService) + public AccountController(IMapper autoMapper, UserService userService) { this._autoMapper = autoMapper; this._userService = userService; } [HttpGet] - [Route("/Register")] + [AllowAnonymous] public IActionResult Register() { return View(); } [HttpPost] - [Route("/Register")] + [AllowAnonymous] public async Task<IActionResult> Register(RegisterUserViewModel registerUserViewModel) { if (!ModelState.IsValid) @@ -43,14 +45,14 @@ namespace ExamTemplate.Web.Controllers } [HttpGet] - [Route("/Login")] + [AllowAnonymous] public IActionResult Login() { return View(); } [HttpPost] - [Route("/Login")] + [AllowAnonymous] public async Task<IActionResult> Login(LoginUserViewModel loginUserViewModel) { if (!ModelState.IsValid) @@ -75,7 +77,7 @@ namespace ExamTemplate.Web.Controllers } [HttpGet] - [Route("/Profile/{username}")] + [AllowAnonymous] public async Task<IActionResult> Profile(string username) { UserServiceModel userServiceModel = await this._userService.GetUserByUsernameAsync(username); @@ -89,8 +91,7 @@ namespace ExamTemplate.Web.Controllers } [HttpGet] - [Route("/EditProfile")] - public async Task<IActionResult> EditProfile() + public async Task<IActionResult> Edit() { UserServiceModel userServiceModel = await this._userService.GetUserByClaimsAsync(this.HttpContext.User); @@ -103,9 +104,11 @@ namespace ExamTemplate.Web.Controllers } [HttpPost] - [Route("/EditProfile")] - public async Task<IActionResult> EditProfile(EditUserViewModel editUserViewModel) + public async Task<IActionResult> Edit(EditUserViewModel editUserViewModel) { + if (!await this._userService.IsAuthorizedToModify(HttpContext.User, editUserViewModel.OriginalUsername)) + return new UnauthorizedResult(); + if (!ModelState.IsValid) return View(editUserViewModel); @@ -127,5 +130,11 @@ namespace ExamTemplate.Web.Controllers else return RedirectToAction("Profile", new { username = loggedInUser.Username }); } + + // [HttpPost] + // public async Task<IActionResult> DeleteProfile(string username) + // { + // throw new System.NotImplementedException(); + // } } } diff --git a/ExamTemplate/Web/Startup.cs b/ExamTemplate/Web/Startup.cs index 0754bff..00d94c0 100644 --- a/ExamTemplate/Web/Startup.cs +++ b/ExamTemplate/Web/Startup.cs @@ -1,5 +1,6 @@ using System;
using System.Linq;
+using ExamTemplate.Common;
using ExamTemplate.Data;
using ExamTemplate.Data.Models;
using ExamTemplate.Services;
@@ -11,9 +12,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace Web
{
- public class Startup
+ public class Startup
{
public Startup(IConfiguration configuration)
{
@@ -41,10 +41,19 @@ namespace Web options.UseNpgsql(this.Configuration.GetConnectionString("LocalDBConnection")));
// Needed for SignInManager and UserManager
- services.AddIdentity<User, Role>()
- .AddRoles<Role>()
+ services.AddIdentity<User, IdentityRole<Guid>>(options =>
+ {
+ options.SignIn.RequireConfirmedAccount = false;
+
+ // Password settings
+ options.Password.RequireDigit = false;
+ options.Password.RequireLowercase = false;
+ options.Password.RequireNonAlphanumeric = false;
+ options.Password.RequireUppercase = false;
+ options.Password.RequiredLength = 3;
+ options.Password.RequiredUniqueChars = 0;
+ }).AddRoles<IdentityRole<Guid>>()
.AddEntityFrameworkStores<TemplateContext>();
-
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -65,8 +74,8 @@ namespace Web app.UseRouting();
- app.UseAuthorization();
app.UseAuthentication();
+ app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
@@ -85,15 +94,15 @@ namespace Web dbContext.Database.Migrate();
- var roleManager = (RoleManager<Role>)serviceScope.ServiceProvider.GetService(typeof(RoleManager<Role>));
- if (!dbContext.Roles.Any(x => x.Name == Role.UserRole))
+ var roleManager = (RoleManager<IdentityRole<Guid>>)serviceScope.ServiceProvider.GetService(typeof(RoleManager<IdentityRole<Guid>>));
+ if (!dbContext.Roles.Any(x => x.Name == RoleConst.User))
{
- Role userRole = new() { Name = Role.UserRole };
+ IdentityRole<Guid> userRole = new() { Name = RoleConst.User };
roleManager.CreateAsync(userRole).Wait();
}
- if (!dbContext.Roles.Any(x => x.Name == Role.AdminRole))
+ if (!dbContext.Roles.Any(x => x.Name == RoleConst.Admin))
{
- Role adminRole = new() { Name = Role.AdminRole };
+ IdentityRole<Guid> adminRole = new() { Name = RoleConst.Admin };
roleManager.CreateAsync(adminRole).Wait();
}
diff --git a/ExamTemplate/Web/Views/User/EditProfile.cshtml b/ExamTemplate/Web/Views/Account/Edit.cshtml index da08d9a..da08d9a 100644 --- a/ExamTemplate/Web/Views/User/EditProfile.cshtml +++ b/ExamTemplate/Web/Views/Account/Edit.cshtml diff --git a/ExamTemplate/Web/Views/User/Login.cshtml b/ExamTemplate/Web/Views/Account/Login.cshtml index 7cb5ac5..688c547 100644 --- a/ExamTemplate/Web/Views/User/Login.cshtml +++ b/ExamTemplate/Web/Views/Account/Login.cshtml @@ -3,7 +3,7 @@ ViewData["Title"] = "Login"; } -<form asp-controller="User" asp-action="Login" method="post"> +<form asp-controller="Account" asp-action="Login" method="post"> <input type="text" asp-for="Username" placeholder="Username"> <span asp-validation-for="Username" class="form-error"></span> diff --git a/ExamTemplate/Web/Views/User/Profile.cshtml b/ExamTemplate/Web/Views/Account/Profile.cshtml index 4120766..c6f3e5c 100644 --- a/ExamTemplate/Web/Views/User/Profile.cshtml +++ b/ExamTemplate/Web/Views/Account/Profile.cshtml @@ -19,7 +19,7 @@ { @if(UserManager.GetUserName(User) == Model.Username) { - <form asp-controller="User" asp-action="EditProfile" method="get"> + <form asp-controller="Account" asp-action="Edit" method="get"> <input type="submit" value="Edit Profile"> </form> } diff --git a/ExamTemplate/Web/Views/User/Register.cshtml b/ExamTemplate/Web/Views/Account/Register.cshtml index 3b7f6d9..d255287 100644 --- a/ExamTemplate/Web/Views/User/Register.cshtml +++ b/ExamTemplate/Web/Views/Account/Register.cshtml @@ -1,6 +1,6 @@ @model ExamTemplate.Web.Models.User.RegisterUserViewModel @{ - ViewData["Title"] = "Register"; + ViewData["Title"] = "Register"; } <form asp-controller="User" asp-action="Register" method="post"> diff --git a/ExamTemplate/Web/Views/Shared/_Navbar.cshtml b/ExamTemplate/Web/Views/Shared/_Navbar.cshtml index 7ae8f50..0ec5c4d 100644 --- a/ExamTemplate/Web/Views/Shared/_Navbar.cshtml +++ b/ExamTemplate/Web/Views/Shared/_Navbar.cshtml @@ -13,18 +13,18 @@ <section> @if (SignInManager.IsSignedIn(User)) { - <a asp-controller="User" asp-action="Profile" asp-route-username="@UserManager.GetUserName(User)"> + <a asp-controller="Account" asp-action="Profile" asp-route-username="@UserManager.GetUserName(User)"> @UserManager.GetUserName(User) </a> - <form asp-controller="User" asp-action="Logout" method="post"> + <form asp-controller="Account" asp-action="Logout" method="post"> <input type="submit" value="Logout"> </form> } else { - <a asp-controller="User" asp-action="Login">Login</a> - <a asp-controller="User" asp-action="Register">Register</a> + <a asp-controller="Account" asp-action="Login">Login</a> + <a asp-controller="Account" asp-action="Register">Register</a> } </section> </div> |
