Partially redo roles

This commit is contained in:
Stanislav Mykhailenko 2023-05-22 19:52:34 +03:00
parent 27c9af7400
commit 90db952f0c
GPG key ID: 1E95E66A9C9D6A36
28 changed files with 180 additions and 206 deletions

View file

@ -1,9 +0,0 @@
namespace NG_2023_Kanban.BusinessLayer.Enums
{
public enum Roles
{
User,
Manager,
Administrator
}
}

View file

@ -10,5 +10,6 @@ namespace NG_2023_Kanban.BusinessLayer.Interfaces
Task UpdateAsync(int id, UserModel user);
Task<UserModel?> LoginAsync(UserModel user);
Task<UserModel> RegisterAsync(UserModel user);
Task<bool> CheckAdminAsync(int id);
}
}

View file

@ -20,6 +20,9 @@ namespace NG_2023_Kanban.BusinessLayer
CreateMap<CommentModel, Comment>()
.ReverseMap();
CreateMap<RoleModel, Role>()
.ReverseMap();
CreateMap<UserModel, User>()
.ReverseMap();
}

View file

@ -4,11 +4,13 @@
{
public string Name { get; set; }
public string Description { get; set; }
public int SenderId { get; set; }
public int AssignedId { get; set; }
public int ColumnId { get; set; }
public int SenderId { get; set; }
public virtual UserModel Sender { get; set; }
public virtual UserModel Assigned { get; set; }
public virtual ColumnModel Column { get; set; }
public virtual UserModel Sender { get; set; }
public virtual ICollection<CommentModel> Comments { get; set; } = new HashSet<CommentModel>();
}

View file

@ -0,0 +1,9 @@
namespace NG_2023_Kanban.BusinessLayer.Models
{
public class RoleModel : BaseModel
{
public string Name { get; set; }
public virtual ICollection<UserModel>? Members { get; set; } = new HashSet<UserModel>();
}
}

View file

@ -1,6 +1,4 @@
using NG_2023_Kanban.BusinessLayer.Enums;
namespace NG_2023_Kanban.BusinessLayer.Models
namespace NG_2023_Kanban.BusinessLayer.Models
{
public class UserModel : BaseModel
{
@ -9,10 +7,10 @@ using NG_2023_Kanban.BusinessLayer.Enums;
public string Username { get; set; }
public string Password { get; set; }
public int Role { get; set; } = (int)Roles.User;
public virtual ICollection<BoardModel>? Boards { get; set; } = new HashSet<BoardModel>();
public virtual ICollection<CardModel>? Cards { get; set; } = new HashSet<CardModel>();
public virtual ICollection<CardModel>? CardsAssigned { get; set; } = new HashSet<CardModel>();
public virtual ICollection<CardModel>? CardsSent { get; set; } = new HashSet<CardModel>();
public virtual ICollection<CommentModel>? Comments { get; set; } = new HashSet<CommentModel>();
public virtual ICollection<RoleModel>? Roles { get; set; } = new HashSet<RoleModel>();
}
}

View file

@ -54,5 +54,20 @@ namespace NG_2023_Kanban.BusinessLayer.Services
await _userRepository.CreateAsync(entity);
return _mapper.Map<UserModel>(entity);
}
public async Task<bool> CheckAdminAsync(int id)
{
var user = await GetAsync(id);
Console.WriteLine(user.Roles.Count);
foreach (RoleModel role in user.Roles)
{
if (role.Name == "Administrator")
{
return true;
}
}
return false;
}
}
}

View file

@ -12,6 +12,7 @@ namespace NG_2023_Kanban.DataLayer.DbStartup
public DbSet<Card> Cards { get; set; }
public DbSet<Column> Columns { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)

View file

@ -16,6 +16,7 @@ namespace NG_2023_Kanban.DataLayer.DbStartup
services.AddTransient<ICardRepository, CardRepository>();
services.AddTransient<IColumnRepository, ColumnRepository>();
services.AddTransient<ICommentRepository, CommentRepository>();
services.AddTransient<IRoleRepository, RoleRepository>();
services.AddTransient<IUserRepository, UserRepository>();
services.AddDbContext<DatabaseContext>(options =>

View file

@ -4,11 +4,13 @@
{
public string Name { get; set; }
public string Description { get; set; }
public int SenderId { get; set; }
public int AssignedId { get; set; }
public int ColumnId { get; set; }
public int SenderId { get; set; }
public virtual User Sender { get; set; }
public virtual User Assigned { get; set; }
public virtual Column Column { get; set; }
public virtual User Sender { get; set; }
public virtual ICollection<Comment> Comments { get; set; } = new HashSet<Comment>();
}

View file

@ -0,0 +1,9 @@
namespace NG_2023_Kanban.DataLayer.Entities
{
public class Role : BaseEntity
{
public string Name { get; set; }
public virtual ICollection<User>? Members { get; set; } = new HashSet<User>();
}
}

View file

@ -1,6 +1,4 @@
using NG_2023_Kanban.DataLayer.Enums;
namespace NG_2023_Kanban.DataLayer.Entities
namespace NG_2023_Kanban.DataLayer.Entities
{
public class User : BaseEntity
{
@ -9,10 +7,10 @@ using NG_2023_Kanban.DataLayer.Enums;
public string Username { get; set; }
public string Password { get; set; }
public int Role { get; set; } = (int)Roles.User;
public virtual ICollection<Board>? Boards { get; set; } = new HashSet<Board>();
public virtual ICollection<Card>? Cards { get; set; } = new HashSet<Card>();
public virtual ICollection<Card>? CardsAssigned { get; set; } = new HashSet<Card>();
public virtual ICollection<Comment>? Comments { get; set; } = new HashSet<Comment>();
public virtual ICollection<Card>? CardsSent { get; set; } = new HashSet<Card>();
public virtual ICollection<Role>? Roles { get; set; } = new HashSet<Role>();
}
}

View file

@ -18,9 +18,9 @@ namespace NG_2023_Kanban.DataLayer.EntityConfiguration
builder.Property(x => x.Description).HasMaxLength(100);
builder
.HasOne(x => x.Sender)
.WithMany(x => x.Cards)
.HasForeignKey(x => x.SenderId)
.HasOne(x => x.Assigned)
.WithMany(x => x.CardsAssigned)
.HasForeignKey(x => x.AssignedId)
.HasPrincipalKey(x => x.Id);
builder
@ -28,6 +28,12 @@ namespace NG_2023_Kanban.DataLayer.EntityConfiguration
.WithMany(x => x.Cards)
.HasForeignKey(x => x.ColumnId)
.HasPrincipalKey(x => x.Id);
builder
.HasOne(x => x.Sender)
.WithMany(x => x.CardsSent)
.HasForeignKey(x => x.SenderId)
.HasPrincipalKey(x => x.Id);
}
}
}

View file

@ -18,11 +18,13 @@ namespace NG_2023_Kanban.DataLayer.EntityConfiguration
builder.Property(x => x.Username).IsRequired();
builder.Property(x => x.Password).IsRequired();
builder.Property(x => x.Role).IsRequired();
builder
.HasMany(x => x.Boards)
.WithMany(x => x.Users);
builder
.HasMany(x => x.Roles)
.WithMany(x => x.Members);
}
}
}

View file

@ -1,9 +0,0 @@
namespace NG_2023_Kanban.DataLayer.Enums
{
public enum Roles
{
User,
Manager,
Administrator
}
}

View file

@ -0,0 +1,8 @@
using NG_2023_Kanban.DataLayer.Entities;
namespace NG_2023_Kanban.DataLayer.Interfaces
{
public interface IRoleRepository : IRepository<Role>
{
}
}

View file

@ -0,0 +1,10 @@
using NG_2023_Kanban.DataLayer.DbStartup;
using NG_2023_Kanban.DataLayer.Entities;
using NG_2023_Kanban.DataLayer.Interfaces;
namespace NG_2023_Kanban.DataLayer.Repositories;
public class RoleRepository : BaseRepository<Role>, IRoleRepository
{
public RoleRepository(DatabaseContext context) : base(context) { }
}

View file

@ -1,10 +1,10 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Http;
using AutoMapper;
using NG_2023_Kanban.Models;
using NG_2023_Kanban.DTOs;
using NG_2023_Kanban.Enums;
using NG_2023_Kanban.BusinessLayer.Models;
using NG_2023_Kanban.BusinessLayer.Services;
@ -25,129 +25,86 @@ public class AdminController : Controller
_mapper = mapper;
}
public async Task<IActionResult> Boards()
public override async void OnActionExecuting(ActionExecutingContext actionContext)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
ViewData["Boards"] = _mapper.Map<ICollection<BoardDto>>(await _boardService.GetAllAsync());
return View();
var userModel = await _userService.GetAsync(currentAccount.Value);
bool isAdmin = await _userService.CheckAdminAsync(userModel.Id);
if (!isAdmin)
{
actionContext.Result = StatusCode(403);
return;
}
ViewData["Account"] = _mapper.Map<UserDto>(userModel);;
ViewData["isAdmin"] = true;
}
return Redirect("/Auth/Login");
else
actionContext.Result = Redirect("/Auth/Login");
}
public async Task<IActionResult> Boards()
{
ViewData["Boards"] = _mapper.Map<ICollection<BoardDto>>(await _boardService.GetAllAsync());
return View();
}
public async Task<IActionResult> Users()
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
ViewData["Users"] = _mapper.Map<ICollection<UserDto>>(await _userService.GetAllAsync());
return View();
}
return Redirect("/Auth/Login");
ViewData["Users"] = _mapper.Map<ICollection<UserDto>>(await _userService.GetAllAsync());
return View();
}
public async Task<IActionResult> EditUser(int id)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
ViewData["EditedAccount"] = _mapper.Map<UserDto>(await _userService.GetAsync(id));
return View();
}
return Redirect("/Auth/Login");
ViewData["EditedAccount"] = _mapper.Map<UserDto>(await _userService.GetAsync(id));
return View();
}
[HttpPost]
public async Task<IActionResult> EditUser(int id, UserDto user)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
ViewData["EditedAccount"] = _mapper.Map<UserDto>(await _userService.GetAsync(id));
//try
//{
user.Id = id;
var model = _mapper.Map<UserModel>(user);
await _userService.UpdateAsync(id, model);
return Redirect("/Admin/Users");
//}
//catch
//{
// ViewData["Error"] = "This name is already taken.";
// return View();
//}
}
return Redirect("/Auth/Login");
ViewData["EditedAccount"] = _mapper.Map<UserDto>(await _userService.GetAsync(id));
//try
//{
user.Id = id;
var model = _mapper.Map<UserModel>(user);
await _userService.UpdateAsync(id, model);
return Redirect("/Admin/Users");
//}
//catch
//{
// ViewData["Error"] = "This name is already taken.";
// return View();
//}
}
public async Task<IActionResult> CreateUser()
public IActionResult CreateUser()
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
return View();
}
return Redirect("/Auth/Login");
return View();
}
[HttpPost]
public async Task<IActionResult> CreateUser(UserDto user)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
try
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
ViewData["Account"] = account;
try
{
var model = _mapper.Map<UserModel>(user);
await _userService.RegisterAsync(model);
return Redirect("/Admin/Users");
}
catch
{
ViewData["Error"] = "This name is already taken.";
return View();
}
var model = _mapper.Map<UserModel>(user);
await _userService.RegisterAsync(model);
return Redirect("/Admin/Users");
}
catch
{
ViewData["Error"] = "This name is already taken.";
return View();
}
return Redirect("/Auth/Login");
}
public async Task<IActionResult> DeleteUser(int id)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
var account = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
if (account.Role < (int)Roles.Administrator)
return StatusCode(StatusCodes.Status403Forbidden);
await _userService.DeleteAsync(id);
return Redirect("/Admin/Users");
}
return Redirect("/Auth/Login");
await _userService.DeleteAsync(id);
return Redirect("/Admin/Users");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]

View file

@ -1,5 +1,6 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using AutoMapper;
using NG_2023_Kanban.Models;
using NG_2023_Kanban.DTOs;
@ -21,22 +22,21 @@ public class AuthController : Controller
_mapper = mapper;
}
public IActionResult Login()
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
actionContext.Result = Redirect("Home/Index");
}
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Login(UserDto user)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
var model = _mapper.Map<UserModel>(user);
var account = _mapper.Map<UserDto>(await _userService.LoginAsync(model));
@ -53,28 +53,14 @@ public class AuthController : Controller
}
}
public IActionResult Logout()
{
HttpContext.Session.Remove("Account");
return Redirect("/Auth/Login");
}
public IActionResult Register()
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
return View();
}
[HttpPost]
public async Task<IActionResult> Register(UserDto user)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
try
{
var model = _mapper.Map<UserModel>(user);

View file

@ -1,5 +1,6 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using AutoMapper;
using NG_2023_Kanban.Models;
using NG_2023_Kanban.DTOs;
@ -21,14 +22,27 @@ public class HomeController : Controller
_mapper = mapper;
}
public async Task<IActionResult> Index()
public override async void OnActionExecuting(ActionExecutingContext actionContext)
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount.HasValue)
{
ViewData["Account"] = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
return View();
var userModel = await _userService.GetAsync(currentAccount.Value);
ViewData["Account"] = _mapper.Map<UserDto>(userModel);
ViewData["isAdmin"] = await _userService.CheckAdminAsync(userModel.Id);
}
else
actionContext.Result = Redirect("/Auth/Login");
}
public IActionResult Index()
{
return View();
}
public IActionResult Logout()
{
HttpContext.Session.Remove("Account");
return Redirect("/Auth/Login");
}

View file

@ -4,11 +4,13 @@
{
public string Name { get; set; }
public string Description { get; set; }
public int SenderId { get; set; }
public int AssignedId { get; set; }
public int ColumnId { get; set; }
public int SenderId { get; set; }
public virtual UserDto Sender { get; set; }
public virtual UserDto Assigned { get; set; }
public virtual ColumnDto Column { get; set; }
public virtual UserDto Sender { get; set; }
public virtual ICollection<CommentDto> Comments { get; set; } = new HashSet<CommentDto>();
}

View file

@ -0,0 +1,9 @@
namespace NG_2023_Kanban.DTOs
{
public class RoleDto : BaseDto
{
public string Name { get; set; }
public virtual ICollection<UserDto>? Members { get; set; } = new HashSet<UserDto>();
}
}

View file

@ -1,5 +1,3 @@
using NG_2023_Kanban.Enums;
namespace NG_2023_Kanban.DTOs
{
public class UserDto : BaseDto
@ -9,10 +7,10 @@ namespace NG_2023_Kanban.DTOs
public string Username { get; set; }
public string Password { get; set; }
public int Role { get; set; } = (int)Roles.User;
public virtual ICollection<BoardDto>? Boards { get; set; } = new HashSet<BoardDto>();
public virtual ICollection<CardDto>? Cards { get; set; } = new HashSet<CardDto>();
public virtual ICollection<CardDto>? CardsAssigned { get; set; } = new HashSet<CardDto>();
public virtual ICollection<CardDto>? CardsSent { get; set; } = new HashSet<CardDto>();
public virtual ICollection<CommentDto>? Comments { get; set; } = new HashSet<CommentDto>();
public virtual ICollection<RoleDto>? Roles { get; set; } = new HashSet<RoleDto>();
}
}

View file

@ -1,9 +0,0 @@
namespace NG_2023_Kanban.Enums
{
public enum Roles
{
User,
Manager,
Administrator
}
}

View file

@ -20,6 +20,9 @@ namespace NG_2023_Kanban
CreateMap<CommentDto, CommentModel>()
.ReverseMap();
CreateMap<RoleDto, RoleModel>()
.ReverseMap();
CreateMap<UserDto, UserModel>()
.ReverseMap();
}

View file

@ -1,5 +1,3 @@
@using NG_2023_Kanban.Enums
@using NG_2023_Kanban.DTOs
@{
ViewData["Title"] = "Create user";
@ -18,16 +16,6 @@
<input type="text" id="username" name="username" required><br>
<label for="password">Password: </label><br>
<input type="password" id="password" name="password" required><br>
<label for="role">Role: </label><br>
<select id="role" name="role" required>
@{
foreach (var role in Roles.GetNames(typeof(Roles)))
{
var roleNumber = (int)Enum.Parse(typeof(Roles), role);
<option value="@roleNumber">@role</option>
}
}
</select><br>
<button id="submit" type="submit">Submit</button>
</form>
</div>

View file

@ -1,5 +1,3 @@
@using NG_2023_Kanban.Enums
@using NG_2023_Kanban.DTOs
@{
var user = ViewData["EditedAccount"] as UserDto;
@ -22,23 +20,6 @@
<input type="text" id="username" name="username" value="@user.Username" required><br>
<label for="password">Password: </label><br>
<input type="password" id="password" name="password"><br>
<label for="role" >Role: </label><br>
<select id="role" name="role" required>
@{
foreach (var role in Roles.GetNames(typeof(Roles)))
{
var roleNumber = (int)Enum.Parse(typeof(Roles), role);
@if (roleNumber == user.Role)
{
<option value="@roleNumber" selected>@role</option>
}
else
{
<option value="@roleNumber">@role</option>
}
}
}
</select><br>
<button id="submit" type="submit">Submit</button>
</form>
</div>

View file

@ -1,6 +1,4 @@
@using NG_2023_Kanban.Enums
@using NG_2023_Kanban.DTOs
@using NG_2023_Kanban.DTOs
@{
var user = ViewData["Account"] as UserDto;
}
@ -31,7 +29,7 @@
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
if (user.Role == (int)Roles.Administrator)
if ((bool)ViewData["isAdmin"])
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="Boards">Boards</a>
@ -50,7 +48,7 @@
}
else
{
<a class="nav-link text-dark" asp-area="" asp-controller="Auth" asp-action="Logout">Log out</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Logout">Log out</a>
}
</li>
</ul>