Add basic admin panel

This commit is contained in:
Stanislav Mykhailenko 2023-05-19 22:38:01 +03:00
parent 3e2b7eeb0e
commit 7716da6799
GPG key ID: 1E95E66A9C9D6A36
13 changed files with 250 additions and 74 deletions

View file

@ -9,6 +9,7 @@ namespace NG_2023_Kanban.BusinessLayer.Inject
this IServiceCollection services)
{
services.AddAutoMapper(typeof(MappingProfile));
services.AddScoped<BoardService>();
services.AddScoped<UserService>();
}
}

View file

@ -0,0 +1,10 @@
using NG_2023_Kanban.BusinessLayer.Models;
namespace NG_2023_Kanban.BusinessLayer.Interfaces
{
public interface IBoardService
{
Task<BoardModel> GetAsync(int id);
Task<ICollection<BoardModel>> GetAllAsync();
}
}

View file

@ -5,6 +5,7 @@ namespace NG_2023_Kanban.BusinessLayer.Interfaces
public interface IUserService
{
Task<UserModel> GetAsync(int id);
Task<ICollection<UserModel>> GetAllAsync();
Task<UserModel?> LoginAsync(UserModel user);
Task<UserModel> RegisterAsync(UserModel user);
}

View file

@ -0,0 +1,31 @@
using AutoMapper;
using NG_2023_Kanban.BusinessLayer.Interfaces;
using NG_2023_Kanban.BusinessLayer.Models;
using NG_2023_Kanban.DataLayer.Repositories;
using NG_2023_Kanban.DataLayer.Entities;
using NG_2023_Kanban.DataLayer.Interfaces;
namespace NG_2023_Kanban.BusinessLayer.Services
{
public class BoardService : IBoardService
{
private readonly IBoardRepository _boardRepository;
private readonly IMapper _mapper;
public BoardService(IBoardRepository boardRepository, IMapper mapper)
{
_boardRepository = boardRepository;
_mapper = mapper;
}
public async Task<BoardModel> GetAsync(int id)
{
return _mapper.Map<BoardModel>(await _boardRepository.GetAsync(id));
}
public async Task<ICollection<BoardModel>> GetAllAsync()
{
return _mapper.Map<ICollection<BoardModel>>(await _boardRepository.GetAllAsync());
}
}
}

View file

@ -23,6 +23,11 @@ namespace NG_2023_Kanban.BusinessLayer.Services
return _mapper.Map<UserModel>(await _userRepository.GetAsync(id));
}
public async Task<ICollection<UserModel>> GetAllAsync()
{
return _mapper.Map<ICollection<UserModel>>(await _userRepository.GetAllAsync());
}
public async Task<UserModel?> LoginAsync(UserModel user)
{
var data = await _userRepository.FindAsync(x => x.Username == user.Username && x.Password == user.Password);

View file

@ -0,0 +1,63 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
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;
namespace NG_2023_Kanban.Controllers;
public class AdminController : Controller
{
private readonly UserService _userService;
private readonly BoardService _boardService;
private readonly ILogger<AdminController> _logger;
private readonly IMapper _mapper;
public AdminController(ILogger<AdminController> logger, UserService userService, BoardService boardService, IMapper mapper)
{
_logger = logger;
_userService = userService;
_boardService = boardService;
_mapper = mapper;
}
public async Task<IActionResult> Boards()
{
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();
}
return Redirect("/Auth/Login");
}
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");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}

View file

@ -0,0 +1,98 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using AutoMapper;
using NG_2023_Kanban.Models;
using NG_2023_Kanban.DTOs;
using NG_2023_Kanban.BusinessLayer.Models;
using NG_2023_Kanban.BusinessLayer.Services;
namespace NG_2023_Kanban.Controllers;
public class AuthController : Controller
{
private readonly UserService _userService;
private readonly ILogger<AuthController> _logger;
private readonly IMapper _mapper;
public AuthController(ILogger<AuthController> logger, UserService userService, IMapper mapper)
{
_logger = logger;
_userService = userService;
_mapper = mapper;
}
public IActionResult Login()
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
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));
if (account != null)
{
HttpContext.Session.SetInt32("Account", account.Id);
return Redirect("/Home/Index");
}
else
{
ViewData["Error"] = "Invalid credentials.";
return View();
}
}
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);
var account = _mapper.Map<UserDto>(await _userService.RegisterAsync(model));
HttpContext.Session.SetInt32("Account", account.Id);
return Redirect("/Home/Index");
}
catch
{
ViewData["Error"] = "This name is already taken.";
return View();
}
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}

View file

@ -29,76 +29,7 @@ public class HomeController : Controller
ViewData["Account"] = _mapper.Map<UserDto>(await _userService.GetAsync(currentAccount.Value));
return View();
}
return Redirect("/Home/Login");
}
public IActionResult Login()
{
var currentAccount = HttpContext.Session.GetInt32("Account");
if (currentAccount != null)
return Redirect("/Home/Index");
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));
if (account != null)
{
HttpContext.Session.SetInt32("Account", account.Id);
return Redirect("/Home/Index");
}
else
{
ViewData["Error"] = "Invalid credentials.";
return View();
}
}
public IActionResult Logout()
{
HttpContext.Session.Remove("Account");
return Redirect("/Home/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);
var account = _mapper.Map<UserDto>(await _userService.RegisterAsync(model));
HttpContext.Session.SetInt32("Account", account.Id);
return Redirect("/Home/Index");
}
catch
{
ViewData["Error"] = "This name is already taken.";
return View();
}
return Redirect("/Auth/Login");
}
public IActionResult Privacy()

View file

@ -0,0 +1,18 @@
@using NG_2023_Kanban.DTOs
@{
var boards = ViewData["Boards"] as ICollection<BoardDto>;
}
@{
ViewData["Title"] = "Boards";
}
<div class="text-center">
<h1 class="display-4">Boards</h1>
@{
foreach (var board in boards)
{
<p>@board.Name</p>
}
}
</div>

View file

@ -0,0 +1,18 @@
@using NG_2023_Kanban.DTOs
@{
var users = ViewData["Users"] as ICollection<UserDto>;
}
@{
ViewData["Title"] = "Users";
}
<div class="text-center">
<h1 class="display-4">Users</h1>
@{
foreach (var user in users)
{
<p>@user.Username</p>
}
}
</div>

View file

@ -34,10 +34,10 @@
if (user.Role == (int)Roles.Administrator)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Boards">Boards</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="Boards">Boards</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Users">Users</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Admin" asp-action="Users">Users</a>
</li>
}
}
@ -46,11 +46,11 @@
<li class="nav-item">
@if (user == null)
{
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Login">Log in</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Auth" asp-action="Login">Log in</a>
}
else
{
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Logout">Log out</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Auth" asp-action="Logout">Log out</a>
}
</li>
</ul>