Работает регистрация, логин и разлогин исполнителя, сделаны проверки на залогиненого пользователя

This commit is contained in:
Никита Потапов 2024-05-29 02:22:44 +04:00
parent 3b067247ad
commit e558327e81
16 changed files with 288 additions and 96 deletions

View File

@ -31,12 +31,19 @@ namespace PolyclinicDatabaseImplement.Implements
public List<UserViewModel> GetFilteredList(UserSearchModel model)
{
var elements = GetFullList();
foreach (var prop in model.GetType().GetProperties())
if (model.Id != null)
{
if (model.GetType().GetProperty(prop.Name)?.GetValue(model, null) != null)
{
elements = elements.Where(x => x.GetType().GetProperty(prop.Name)?.GetValue(x, null) == model.GetType().GetProperty(prop.Name)?.GetValue(model, null)).ToList();
elements = elements.Where(x => x.Id == model.Id).ToList();
}
if (!model.Email.IsNullOrEmpty())
{
elements = elements.Where(x => x.Email == model.Email).ToList();
}
if (!model.Password.IsNullOrEmpty())
{
elements = elements.Where(x => x.Password == model.Password).ToList();
}
return elements;
}

View File

@ -22,6 +22,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpGet]
public IActionResult Index()
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
List<CourseViewModel> courses = _courseLogic.ReadList();
ViewData["Title"] = "Список курсов";
return View("CoursesList", courses);
@ -30,6 +35,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Add(CourseFormModel model, int[] selectedDiagnoses)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
if (HttpContext.Request.Method == "GET")
{
ViewData["Title"] = "Новый курс";
@ -61,6 +71,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Edit(int id, CourseFormModel model, int[] selectedDiagnoses)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
if (HttpContext.Request.Method == "GET")
{
var obj = _courseLogic.ReadElement(new CourseSearchModel { Id = id });
@ -94,6 +109,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Delete(int id)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
var obj = _courseLogic.ReadElement(new CourseSearchModel { Id = id });
if (obj != null)
{

View File

@ -4,6 +4,7 @@ using PolyclinicContracts.BusinessLogicsContracts;
using PolyclinicContracts.SearchModels;
using PolyclinicContracts.ViewModels;
using PolyclinicWebAppImplementer.Models;
using System.Net;
namespace PolyclinicWebAppImplementer.Controllers
{
@ -21,8 +22,12 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpGet]
public IActionResult Index()
{
// TODO выводить только пользовательские диагнозы
List<DiagnoseViewModel> diagnoses = _diagnoseLogic.ReadList();
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
List<DiagnoseViewModel> diagnoses = _diagnoseLogic.ReadList(new DiagnoseSearchModel { UserId = currentUser.Id });
ViewData["Title"] = "Список диагнозов";
return View("DiagnosesList", diagnoses);
}
@ -31,6 +36,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Add(DiagnoseViewModel model)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
if (HttpContext.Request.Method == "GET")
{
ViewData["Title"] = "Новый диагноз";
@ -38,9 +48,9 @@ namespace PolyclinicWebAppImplementer.Controllers
}
else
{
// TODO прописать UserId
DiagnoseBindingModel diagnose = new DiagnoseBindingModel
{
UserId = currentUser.Id,
Name = model.Name,
Comment = model.Comment,
DateStartDiagnose = model.DateStartDiagnose,
@ -55,10 +65,18 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Edit(int id, DiagnoseViewModel model)
{
// TODO проверить, что пользователь хочет редактировать свой диагноз (UserId)
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id });
if (obj.UserId != currentUser.Id)
{
return StatusCode(403, "Нельзя редактировать чужой диагноз");
}
if (HttpContext.Request.Method == "GET")
{
var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id });
ViewData["Title"] = "Редактировать диагноз";
return View("DiagnoseForm", obj);
}
@ -80,8 +98,16 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Delete(int id)
{
// TODO проверить, что пользователь хочет удалить свой диагноз (UserId)
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id });
if (obj.UserId != currentUser.Id)
{
return StatusCode(403, "Нельзя удалить чужой диагноз");
}
if (obj != null)
{
_diagnoseLogic.Delete(new DiagnoseBindingModel { Id = obj.Id });

View File

@ -17,63 +17,12 @@ namespace PolyclinicWebAppImplementer.Controllers
{
return View();
}
[HttpGet]
[HttpPost]
public IActionResult Course()
{
if (HttpContext.Request.Method == "POST")
{
return Redirect("~/Home/Courses");
}
else
{
return View();
}
}
public IActionResult Courses()
{
return View();
}
public IActionResult Symptom()
{
if (HttpContext.Request.Method == "POST")
{
return Redirect("~/Home/Symptomes");
}
else
{
return View();
}
}
public IActionResult Symptomes()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[HttpGet]
[HttpPost]
public IActionResult Login()
{
if (HttpContext.Request.Method == "POST")
{
return Redirect("~/");
}
else
{
return View();
}
}
public IActionResult Register()
{
return View();
}
[HttpGet]
[HttpPost]
public IActionResult AddRecipeToCourse()

View File

@ -20,6 +20,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpGet]
public IActionResult Index()
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
List<SymptomViewModel> symptomes = _symptomLogic.ReadList();
ViewData["Title"] = "Список симптомов";
return View("SymptomesList", symptomes);
@ -28,6 +33,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Add(SymptomFormModel model, int[] selectedDiagnoses)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
if (HttpContext.Request.Method == "GET")
{
ViewData["Title"] = "Новый симптом";
@ -58,6 +68,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Edit(int id, SymptomFormModel model, int[] selectedDiagnoses)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
if (HttpContext.Request.Method == "GET")
{
var obj = _symptomLogic.ReadElement(new SymptomSearchModel { Id = id });
@ -90,6 +105,11 @@ namespace PolyclinicWebAppImplementer.Controllers
[HttpPost]
public IActionResult Delete(int id)
{
var currentUser = LoginManager.LogginedUser;
if (currentUser == null)
{
return RedirectToAction("Login", "User");
}
var obj = _symptomLogic.ReadElement(new SymptomSearchModel { Id = id });
if (obj != null)
{

View File

@ -0,0 +1,98 @@
using Microsoft.AspNetCore.Mvc;
using PolyclinicContracts.BindingModels;
using PolyclinicContracts.BusinessLogicsContracts;
using PolyclinicContracts.SearchModels;
using PolyclinicDataModels.Enums;
using PolyclinicDataModels.Models;
using PolyclinicWebAppImplementer.Models;
namespace PolyclinicWebAppImplementer.Controllers
{
public class UserController : Controller
{
private readonly IUserLogic _userLogic;
public UserController(IUserLogic userLogic)
{
_userLogic = userLogic;
}
[HttpGet]
[HttpPost]
public IActionResult Login(LoginModel model)
{
var errors = new List<string>();
if (HttpContext.Request.Method == "POST")
{
var user = _userLogic.ReadElement(new UserSearchModel { Email = model.Email, Password = model.Password });
if (user == null)
{
errors.Add("Неверные логин или пароль");
}
else if (user.Role != UserRole.Исполнитель)
{
errors.Add("Пользователь имеет неразрешенную роль");
}
if (errors.Count > 0)
{
model = new LoginModel
{
Errors = errors
};
return View(model);
}
LoginManager.LogginedUser = user;
return RedirectToAction("", "Home");
}
else
{
model = new();
return View(model);
}
}
[HttpGet]
[HttpPost]
public IActionResult Register(RegisterModel model)
{
var errors = new List<string>();
if (HttpContext.Request.Method == "POST")
{
if (_userLogic.ReadElement(new UserSearchModel { Email = model.Email }) != null)
{
errors.Add("Пользователь с таким Email уже есть");
}
if (model.Password != model.ConfirmPassword)
{
errors.Add("Пароли не совпадают");
}
if (errors.Count > 0)
{
model.Errors = errors;
model.Password = string.Empty;
model.ConfirmPassword = string.Empty;
return View(model);
}
var user = new UserBindingModel
{
FIO = model.FIO,
Email = model.Email,
Password = model.Password,
Role = UserRole.Исполнитель
};
_userLogic.Create(user);
return RedirectToAction("Login");
}
else
{
return View(model);
}
}
[HttpPost]
public IActionResult Logout()
{
LoginManager.LogginedUser = null;
return RedirectToAction("Login");
}
}
}

View File

@ -0,0 +1,9 @@
using PolyclinicContracts.ViewModels;
namespace PolyclinicWebAppImplementer
{
public static class LoginManager
{
public static UserViewModel? LogginedUser { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace PolyclinicWebAppImplementer.Models
{
public class LoginModel
{
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public List<string> Errors { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
namespace PolyclinicWebAppImplementer.Models
{
public class RegisterModel
{
public string FIO { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string ConfirmPassword { get; set; } = string.Empty;
public List<string> Errors = new();
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -18,7 +18,7 @@
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="Views\Home\Register.cshtml">
<Content Update="Views\User\Register.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>

View File

@ -17,6 +17,9 @@ builder.Services.AddTransient<IDiagnoseStorage, DiagnoseStorage>();
builder.Services.AddTransient<ICourseStorage, CourseStorage>();
builder.Services.AddTransient<ISymptomStorage, SymptomStorage>();
builder.Services.AddTransient<IUserStorage, UserStorage>();
builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<IProcedureLogic, ProcedureLogic>();
builder.Services.AddTransient<IMedicamentLogic, MedicamentLogic>();
builder.Services.AddTransient<IRecipeLogic, RecipeLogic>();

View File

@ -0,0 +1,9 @@
namespace PolyclinicWebAppImplementer
{
public enum PageVisible
{
AllowAnyBody = 0,
AllowOnlyAuthorized = 1,
AllowOnlyNotAuthorized = 2,
}
}

View File

@ -2,18 +2,18 @@
{
public static class SiteMenuItems
{
public static (string Controller, string Action, string Title) Index = ("Home", "", "Главная");
public static (string Controller, string Action, string Title) Courses = ("Courses", "", "Курсы");
public static (string Controller, string Action, string Title) Diagnoses = ("Diagnoses", "", "Болезни");
public static (string Controller, string Action, string Title) Symptomes = ("Symptomes", "", "Симптомы");
public static (string Controller, string Action, string Title) Login = ("Home", "Login", "Вход");
public static (string Controller, string Action, string Title) Register = ("Home", "Register", "Регистрация");
public static (string Controller, string Action, string Title) Privacy = ("Home", "Privacy", "Политика приватности");
public static (string Controller, string Action, string Title) AddRecipeToCourse = ("Home", "AddRecipeToCourse", "Привязка рецепта");
public static (string Controller, string Action, string Title) MedicamentsByDiagnoses = ("Home", "MedicamentsByDiagnoses", "Лекарства по болезням");
public static (string Controller, string Action, string Title) DiagnosesReport = ("Home", "DiagnosesReport", "Отчет по болезням");
public static (string Controller, string Action, string Title, PageVisible Visible) Index = ("Home", "", "Главная", PageVisible.AllowAnyBody);
public static (string Controller, string Action, string Title, PageVisible Visible) Courses = ("Courses", "", "Курсы", PageVisible.AllowOnlyAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) Diagnoses = ("Diagnoses", "", "Болезни", PageVisible.AllowOnlyAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) Symptomes = ("Symptomes", "", "Симптомы", PageVisible.AllowOnlyAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) Login = ("User", "Login", "Вход", PageVisible.AllowOnlyNotAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) Register = ("User", "Register", "Регистрация", PageVisible.AllowOnlyNotAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) Privacy = ("Home", "Privacy", "Политика приватности", PageVisible.AllowAnyBody);
public static (string Controller, string Action, string Title, PageVisible Visible) AddRecipeToCourse = ("Home", "AddRecipeToCourse", "Привязка рецепта", PageVisible.AllowOnlyAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) MedicamentsByDiagnoses = ("Home", "MedicamentsByDiagnoses", "Лекарства по болезням", PageVisible.AllowOnlyAuthorized);
public static (string Controller, string Action, string Title, PageVisible Visible) DiagnosesReport = ("Home", "DiagnosesReport", "Отчет по болезням", PageVisible.AllowOnlyAuthorized);
public static List<(string Controller, string Action, string Title)> MenuItemsOrder = new List<(string Controller, string Action, string Title)>
public static List<(string Controller, string Action, string Title, PageVisible Visible)> MenuItemsOrder = new List<(string Controller, string Action, string Title, PageVisible Visible)>
{
Index, Courses, Diagnoses, Symptomes, Login, Register, AddRecipeToCourse, MedicamentsByDiagnoses, DiagnosesReport
};

View File

@ -31,6 +31,10 @@
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
@foreach (var menuItem in SiteMenuItems.MenuItemsOrder)
{
@if (menuItem.Visible == PageVisible.AllowAnyBody ||
LoginManager.LogginedUser == null && menuItem.Visible == PageVisible.AllowOnlyNotAuthorized ||
LoginManager.LogginedUser != null && menuItem.Visible == PageVisible.AllowOnlyAuthorized)
{
<li class="menu-item">
@Html.RouteLink(menuItem.Title, new
@ -44,7 +48,14 @@
)
</li>
}
}
</ul>
@if(LoginManager.LogginedUser != null)
{
<form method="post" asp-action="Logout" asp-controller="User">
<button class="btn btn-secondary" type="submit">Выйти</button>
</form>
}
</div>
</div>
</nav>

View File

@ -1,20 +1,27 @@
@{
@model LoginModel
@{
ViewBag.SelectedSiteMenuItem = SiteMenuItems.Login;
}
<div class="d-flex w-100 h-100 align-content-center justify-content-center">
<form class="d-flex flex-column" id="loginForm"method="post">
<h4>Вход</h4>
@foreach (var item in Model.Errors)
{
<div class="alert alert-danger" role="alert">
@item
</div>
}
<div class="mb-2 d-flex w-100">
<label for="emailInput" class="me-2">
Email
</label>
<input id="emailInput" type="email" name="email" placeholder="mail@example.com" class="w-100"/>
<input id="emailInput" required type="email" placeholder="mail@example.com" asp-for="Email" class="w-100"/>
</div>
<div class="mb-2 d-flex w-100">
<label for="passwordInput" class="me-2">
Пароль
</label>
<input id="passwordInput" type="password" name="password" class="w-100"/>
<input id="passwordInput" required type="password" asp-for="Password" class="w-100"/>
</div>
<button class="btn btn-outline-primary" type="submit">
Войти

View File

@ -1,26 +1,39 @@
@{
@model RegisterModel
@{
ViewBag.SelectedSiteMenuItem = SiteMenuItems.Register;
}
<div class="d-flex w-100 h-100 align-content-center justify-content-center">
<form class="d-flex flex-column" id="registerForm" method="post">
<h4>Регистрация</h4>
<h4>Регистрация исполнителя</h4>
@foreach (var item in Model.Errors)
{
<div class="alert alert-danger" role="alert">
@item
</div>
}
<div class="mb-2 d-flex w-100">
<label for="fioInput" class="me-2">
ФИО
</label>
<input id="fioInput" name="fio" type="text" placeholder="Иванов Иван Иванович" class="w-100" />
<input id="fioInput" required asp-for="FIO" placeholder="Иванов Иван Иванович" class="w-100" />
</div>
<div class="mb-2 d-flex w-100">
<label for="emailInput" class="me-2">
Email
</label>
<input id="emailInput" type="email" name="email" placeholder="mail@example.com" class="w-100" />
<input id="emailInput" required type="email" asp-for="Email" placeholder="mail@example.com" class="w-100" />
</div>
<div class="mb-2 d-flex w-100">
<label for="passwordInput" class="me-2">
Пароль
</label>
<input id="passwordInput" type="password" name="password" class="w-100" />
<input id="passwordInput" required type="password" asp-for="Password" class="w-100" />
</div>
<div class="mb-2 d-flex w-100">
<label for="confirmPasswordInput" class="me-2">
Повторите пароль
</label>
<input id="confirmPasswordInput" required type="password" asp-for="ConfirmPassword" class="w-100" />
</div>
<button class="btn btn-outline-success" type="submit">
Зарегистрироваться