aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2021-05-08 18:10:08 +0300
committerSyndamia <kamen.d.mladenov@protonmail.com>2021-05-08 18:10:08 +0300
commit82d270a66b8ffca28e321f29b2eb90b2412ac9a7 (patch)
treebd7e985592a0d8d5ec31b590b3c52d403e17e140
parenta1e46b76a1299e35b1ac8cae69e77c66d74224a6 (diff)
downloadit-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.cs8
-rw-r--r--ExamTemplate/Data/Models/Role.cs16
-rw-r--r--ExamTemplate/Data/Models/User.cs1
-rw-r--r--ExamTemplate/Data/TemplateContext.cs7
-rw-r--r--ExamTemplate/Services/UserService.cs15
-rw-r--r--ExamTemplate/Web/Controllers/AccountController.cs (renamed from ExamTemplate/Web/Controllers/UserController.cs)31
-rw-r--r--ExamTemplate/Web/Startup.cs31
-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.cshtml8
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>