From 90b9d3bb752e143b9da7187124cbe60c9f11cd48 Mon Sep 17 00:00:00 2001 From: Pat Hartl Date: Tue, 17 Jan 2023 17:21:38 -0600 Subject: [PATCH] Added basic user management --- .../Controllers/SettingsController.cs | 112 +++++++++++++++++- LANCommander/Models/UserViewModel.cs | 9 ++ LANCommander/Views/Settings/General.cshtml | 2 +- LANCommander/Views/Settings/Users.cshtml | 82 +++++++++++++ .../Views/Settings/_SidebarPartial.cshtml | 1 + 5 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 LANCommander/Models/UserViewModel.cs create mode 100644 LANCommander/Views/Settings/Users.cshtml diff --git a/LANCommander/Controllers/SettingsController.cs b/LANCommander/Controllers/SettingsController.cs index 4a7b867..fc41a5d 100644 --- a/LANCommander/Controllers/SettingsController.cs +++ b/LANCommander/Controllers/SettingsController.cs @@ -1,18 +1,22 @@ -using LANCommander.Models; +using LANCommander.Data.Models; +using LANCommander.Models; using LANCommander.Services; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; namespace LANCommander.Controllers { - [Authorize] - public class SettingsController : Controller + [Authorize(Roles = "Administrator")] + public class SettingsController : BaseController { private readonly SettingService SettingService; + private readonly UserManager UserManager; - public SettingsController(SettingService settingService) + public SettingsController(SettingService settingService, UserManager userManager) { SettingService = settingService; + UserManager = userManager; } public IActionResult Index() @@ -34,5 +38,105 @@ namespace LANCommander.Controllers return RedirectToAction(nameof(General)); } + + public async Task Users() + { + var users = new List(); + + foreach (var user in UserManager.Users) + { + users.Add(new UserViewModel() + { + Id = user.Id, + UserName = user.UserName, + Roles = await UserManager.GetRolesAsync(user) + }); + } + + return View(users); + } + + public async Task DeleteUser(Guid id) + { + var user = await UserManager.FindByIdAsync(id.ToString()); + var admins = await UserManager.GetUsersInRoleAsync("Administrator"); + + if (user.UserName == HttpContext.User.Identity.Name) + { + Alert("You cannot delete yourself!", "danger"); + + return RedirectToAction(nameof(Users)); + } + + if (admins.Count == 1 && admins.First().Id == id) + { + Alert("You cannot delete the only admin user!", "danger"); + + return RedirectToAction(nameof(Users)); + } + + try + { + await UserManager.DeleteAsync(user); + + Alert("User successfully deleted!", "success"); + + return RedirectToAction(nameof(Users)); + } + catch + { + Alert("User could not be deleted!", "danger"); + + return RedirectToAction(nameof(Users)); + } + } + + public async Task PromoteUser(Guid id) + { + var user = await UserManager.FindByIdAsync(id.ToString()); + + try + { + await UserManager.AddToRoleAsync(user, "Administrator"); + + Alert("User promoted to administrator!", "success"); + + return RedirectToAction(nameof(Users)); + } + catch (Exception ex) + { + Alert("User could not be promoted!", "danger"); + + return RedirectToAction(nameof(Users)); + } + } + + public async Task DemoteUser(Guid id) + { + var user = await UserManager.FindByIdAsync(id.ToString()); + var admins = await UserManager.GetUsersInRoleAsync("Administrator"); + + if (user.UserName == HttpContext.User.Identity.Name) + { + Alert("You cannot demote yourself!", "danger"); + + return RedirectToAction(nameof(Users)); + } + + try + { + await UserManager.RemoveFromRoleAsync(user, "Administrator"); + + Alert("User successfully demoted!", "success"); + + return RedirectToAction(nameof(Users)); + } + catch + { + Alert("User could not be demoted!", "danger"); + + return RedirectToAction(nameof(Users)); + } + } } } diff --git a/LANCommander/Models/UserViewModel.cs b/LANCommander/Models/UserViewModel.cs new file mode 100644 index 0000000..70ed86b --- /dev/null +++ b/LANCommander/Models/UserViewModel.cs @@ -0,0 +1,9 @@ +namespace LANCommander.Models +{ + public class UserViewModel + { + public Guid Id { get; set; } + public string UserName { get; set; } + public IEnumerable Roles { get; set; } + } +} diff --git a/LANCommander/Views/Settings/General.cshtml b/LANCommander/Views/Settings/General.cshtml index cd5f9b5..19588bd 100644 --- a/LANCommander/Views/Settings/General.cshtml +++ b/LANCommander/Views/Settings/General.cshtml @@ -1,7 +1,7 @@ @model LANCommander.Models.LANCommanderSettings @{ - ViewData["Title"] = "Settings"; + ViewData["Title"] = "Settings | Users"; }
diff --git a/LANCommander/Views/Settings/Users.cshtml b/LANCommander/Views/Settings/Users.cshtml new file mode 100644 index 0000000..7b888f1 --- /dev/null +++ b/LANCommander/Views/Settings/Users.cshtml @@ -0,0 +1,82 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Settings | Users"; +} + +
+ + +
+ +
+
+
+
+ @{ + await Html.RenderPartialAsync("_SidebarPartial"); + } + +
+
+

Users

+
+ +
+ + + + + + + + + + + @foreach (var item in Model.OrderBy(u => u.UserName)) + { + + + + + + } + +
UsernameRole
+ @item.UserName + + @String.Join(", ", item.Roles) + +
+ @if (!item.Roles.Any(r => r == "Administrator")) + { + Promote + } + else + { + Demote + } + Delete +
+
+
+
+
+
+
+
+ +@section Scripts { + @{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); + } +} diff --git a/LANCommander/Views/Settings/_SidebarPartial.cshtml b/LANCommander/Views/Settings/_SidebarPartial.cshtml index ca6df5a..6e8578a 100644 --- a/LANCommander/Views/Settings/_SidebarPartial.cshtml +++ b/LANCommander/Views/Settings/_SidebarPartial.cshtml @@ -2,6 +2,7 @@
\ No newline at end of file