From 4ba55686a5aec4324533dadea6dbd60df6e8bbd3 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Sat, 3 Aug 2024 11:57:10 +0200 Subject: [PATCH] Converted edit page to modal and added edit and create permissions --- HopFrame.Web/AdminPermissions.cs | 1 + HopFrame.Web/Model/RegisterData.cs | 4 +- .../Components/UserAddModal.razor | 92 +++++- .../Components/UserEditModal.razor | 307 ++++++++++++++++++ .../Pages/Administration/UserEditPage.razor | 292 ----------------- .../Pages/Administration/UsersPage.razor | 65 +--- 6 files changed, 394 insertions(+), 367 deletions(-) create mode 100644 HopFrame.Web/Pages/Administration/Components/UserEditModal.razor delete mode 100644 HopFrame.Web/Pages/Administration/UserEditPage.razor diff --git a/HopFrame.Web/AdminPermissions.cs b/HopFrame.Web/AdminPermissions.cs index 47221ed..36ac057 100644 --- a/HopFrame.Web/AdminPermissions.cs +++ b/HopFrame.Web/AdminPermissions.cs @@ -5,4 +5,5 @@ public static class AdminPermissions { public const string ViewUsers = "hopframe.admin.users.view"; public const string EditUsers = "hopframe.admin.users.edit"; public const string DeleteUsers = "hopframe.admin.users.delete"; + public const string AddUser = "hopframe.admin.users.add"; } \ No newline at end of file diff --git a/HopFrame.Web/Model/RegisterData.cs b/HopFrame.Web/Model/RegisterData.cs index b987c5a..8f19f15 100644 --- a/HopFrame.Web/Model/RegisterData.cs +++ b/HopFrame.Web/Model/RegisterData.cs @@ -6,6 +6,6 @@ public class RegisterData : UserRegister { public string RepeatedPassword { get; set; } public bool PasswordsMatch => Password == RepeatedPassword; - public bool PasswordIsValid => Password.Length >= 8; - public bool EmailIsValid => Email.Contains('@') && Email.Contains('.') && !Email.EndsWith('.'); + public bool PasswordIsValid => Password?.Length >= 8; + public bool EmailIsValid => Email?.Contains('@') == true && Email?.Contains('.') == true && Email?.EndsWith('.') == false; } \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/Components/UserAddModal.razor b/HopFrame.Web/Pages/Administration/Components/UserAddModal.razor index d905830..5090d5f 100644 --- a/HopFrame.Web/Pages/Administration/Components/UserAddModal.razor +++ b/HopFrame.Web/Pages/Administration/Components/UserAddModal.razor @@ -4,31 +4,33 @@ @using static Microsoft.AspNetCore.Components.Web.RenderMode @using BlazorStrap.Shared.Components.Modal @using BlazorStrap.V5 +@using CurrieTechnologies.Razor.SweetAlert2 @using HopFrame.Database.Models +@using HopFrame.Security.Claims @using HopFrame.Security.Services @using HopFrame.Web.Model - - - Add user + + + Add user
- E-Mail + E-Mail
- Username + Username
- Password + Password
- Primary group + Primary group @@ -39,31 +41,91 @@
- Cancel + Cancel Save
+@inject IUserService Users @inject IPermissionService Permissions +@inject SweetAlertService Alerts +@inject ITokenContext Auth @code { - [Parameter] public Action OnSubmit { get; set; } + [Parameter] public Func ReloadPage { get; set; } private IList _allGroups = new List(); + private IList _allUsers = new List(); private UserAdd _user; private BSModalBase _modal; - protected override async Task OnInitializedAsync() { + public async Task ShowAsync() { _allGroups = await Permissions.GetPermissionGroups(); + _allUsers = await Users.GetUsers(); + + await _modal.ShowAsync(); } - public Task ShowAsync() { - return _modal.ShowAsync(); - } + private async Task AddUser() { + if (!(await Permissions.HasPermission(AdminPermissions.AddUser, Auth.User.Id))) { + await NoAddPermissions(); + return; + } + + string errorMessage = null; + + if (_allUsers.Any(user => user.Username == _user.Username)) { + errorMessage = "Username is already taken!"; + } + else if (_allUsers.Any(user => user.Email == _user.Email)) { + errorMessage = "E-Mail is already taken!"; + } + else if (!_user.PasswordIsValid) { + errorMessage = "The password needs to be at least 8 characters long!"; + } + else if (!_user.EmailIsValid) { + errorMessage = "Invalid E-Mail address!"; + } + else if (string.IsNullOrWhiteSpace(_user.Username)) { + errorMessage = "You need to set a username!"; + } - private void Submit() { - OnSubmit.Invoke(_user); + if (!string.IsNullOrWhiteSpace(errorMessage)) { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Something went wrong!", + Text = errorMessage, + Icon = SweetAlertIcon.Error, + ShowConfirmButton = false, + Timer = 1500 + }); + + return; + } + + var user = await Users.AddUser(_user); + + if (!string.IsNullOrWhiteSpace(_user.Group)) { + await Permissions.AddPermission(user, _user.Group); + } + + await ReloadPage.Invoke(); + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "New user added!", + Icon = SweetAlertIcon.Success, + ShowConfirmButton = false, + Timer = 1500 + + }); + } + + private async Task NoAddPermissions() { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Unauthorized!", + Text = "You don't have the required Permissions to edit a user!", + Icon = SweetAlertIcon.Error + }); } } \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/Components/UserEditModal.razor b/HopFrame.Web/Pages/Administration/Components/UserEditModal.razor new file mode 100644 index 0000000..330750b --- /dev/null +++ b/HopFrame.Web/Pages/Administration/Components/UserEditModal.razor @@ -0,0 +1,307 @@ +@rendermode InteractiveServer + +@using BlazorStrap +@using BlazorStrap.Shared.Components.Modal +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using BlazorStrap.V5 +@using CurrieTechnologies.Razor.SweetAlert2 +@using HopFrame.Database.Models +@using HopFrame.Security.Claims +@using HopFrame.Security.Services +@using HopFrame.Web.Model +@using HopFrame.Web.Services + + + + Edit @_user.Username + +
+ User id + +
+
+ Created at + +
+
+ E-Mail + +
+
+ Username + +
+
+ Password + +
+ +
+ Groups + + + + @foreach (var group in _userGroups) { + + + + + + @group.Name.Replace("group.", "") + + } + + + +
+ + + + @foreach (var group in _allGroups) { + @if (_userGroups.All(g => g.Name != group.Name)) { + + } + } + + Add +
+
+
+
+ +
+ Permissions + + + + @foreach (var perm in _user.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) { + + + + + + @perm.PermissionName + + } + + + +
+ + Add +
+
+
+
+
+ + Cancel + Save + +
+
+ +@inject IUserService Users +@inject IPermissionService Permissions +@inject SweetAlertService Alerts +@inject ITokenContext Auth + +@code { + [Parameter] public Func ReloadPage { get; set; } + + private BSModalBase _modal; + private User _user; + private string _newPassword; + + private IList _userGroups; + private IList _allGroups; + private string _selectedGroup; + private string _permissionToAdd; + + public async Task ShowAsync(User user) { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + _user = user; + _userGroups = await Permissions.GetUserPermissionGroups(_user); + _allGroups = await Permissions.GetPermissionGroups(); + await _modal.ShowAsync(); + } + + private async Task AddGroup() { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + if (string.IsNullOrWhiteSpace(_selectedGroup)) { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Select a group!", + Icon = SweetAlertIcon.Error, + ShowConfirmButton = true + }); + return; + } + + var group = _allGroups.SingleOrDefault(group => group.Name == _selectedGroup); + + await Permissions.AddPermission(_user, group?.Name); + _userGroups.Add(group); + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Group added!", + Icon = SweetAlertIcon.Success, + Timer = 1500, + ShowConfirmButton = false + }); + } + + private async Task RemoveGroup(PermissionGroup group) { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + var result = await Alerts.FireAsync(new SweetAlertOptions { + Title = "Are you sure?", + Icon = SweetAlertIcon.Warning, + ConfirmButtonText = "Yes", + ShowCancelButton = true, + ShowConfirmButton = true + }); + + if (result.IsConfirmed) { + await Permissions.RemoveGroupFromUser(_user, group); + _userGroups.Remove(group); + StateHasChanged(); + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Group removed!", + Icon = SweetAlertIcon.Success, + Timer = 1500, + ShowConfirmButton = false + }); + } + } + + private async Task AddPermission() { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + if (string.IsNullOrWhiteSpace(_permissionToAdd)) { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Enter a permission name!", + Icon = SweetAlertIcon.Error, + ShowConfirmButton = true + }); + return; + } + + await Permissions.AddPermission(_user, _permissionToAdd); + _user.Permissions.Add(await Permissions.GetPermission(_permissionToAdd, _user)); + _permissionToAdd = ""; + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Permission added!", + Icon = SweetAlertIcon.Success, + Timer = 1500, + ShowConfirmButton = false + }); + } + + private async Task RemovePermission(Permission perm) { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + var result = await Alerts.FireAsync(new SweetAlertOptions { + Title = "Are you sure?", + Icon = SweetAlertIcon.Warning, + ConfirmButtonText = "Yes", + ShowCancelButton = true, + ShowConfirmButton = true + }); + + if (result.IsConfirmed) { + await Permissions.RemovePermission(perm); + _user.Permissions.Remove(perm); + StateHasChanged(); + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Permission removed!", + Icon = SweetAlertIcon.Success, + Timer = 1500, + ShowConfirmButton = false + }); + } + } + + private async void EditUser() { + if (!(await Permissions.HasPermission(AdminPermissions.EditUsers, Auth.User.Id))) { + await NoEditPermissions(); + return; + } + + string errorMessage = null; + var validator = new RegisterData { + Password = _newPassword, + Email = _user.Email + }; + + var allUsers = await Users.GetUsers(); + + if (allUsers.Any(user => user.Username == _user.Username && user.Id != _user.Id)) { + errorMessage = "Username is already taken!"; + } + else if (allUsers.Any(user => user.Email == _user.Email && user.Id != _user.Id)) { + errorMessage = "E-Mail is already taken!"; + } + else if (!string.IsNullOrWhiteSpace(_newPassword) && !validator.PasswordIsValid) { + errorMessage = "The password needs to be at least 8 characters long!"; + } + else if (!validator.EmailIsValid) { + errorMessage = "Invalid E-Mail address!"; + } + + if (!string.IsNullOrWhiteSpace(errorMessage)) { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Something went wrong!", + Text = errorMessage, + Icon = SweetAlertIcon.Error, + ShowConfirmButton = false, + Timer = 1500 + }); + + return; + } + + await Users.UpdateUser(_user); + + if (!string.IsNullOrWhiteSpace(_newPassword)) { + await Users.ChangePassword(_user, _newPassword); + } + + if (ReloadPage is not null) + await ReloadPage.Invoke(); + + await Alerts.FireAsync(new SweetAlertOptions { + Title = "User edited!", + Icon = SweetAlertIcon.Success, + Timer = 1500, + ShowConfirmButton = false + }); + } + + private async Task NoEditPermissions() { + await Alerts.FireAsync(new SweetAlertOptions { + Title = "Unauthorized!", + Text = "You don't have the required Permissions to edit a user!", + Icon = SweetAlertIcon.Error + }); + } +} \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/UserEditPage.razor b/HopFrame.Web/Pages/Administration/UserEditPage.razor deleted file mode 100644 index b32a03b..0000000 --- a/HopFrame.Web/Pages/Administration/UserEditPage.razor +++ /dev/null @@ -1,292 +0,0 @@ -@page "/administration/user/{UserId}" - -@using CurrieTechnologies.Razor.SweetAlert2 -@using HopFrame.Database.Models -@using HopFrame.Security.Services -@using HopFrame.Web.Pages.Administration.Layout -@using Microsoft.AspNetCore.Components.Web -@using static Microsoft.AspNetCore.Components.Web.RenderMode -@using Microsoft.AspNetCore.Components.Forms -@using HopFrame.Web.Components -@using HopFrame.Web.Pages.Administration.Components - -@layout AdminLayout -@rendermode InteractiveServer - -Edit @User.Username - - -

Edit @User.Username (@User.Id)

- - - @**@ -
-
- - -
-
- - - -
-
- - - -
-
- - -
- -
- -
    -
  • -
      - @foreach (var group in _groups) { -
    • - - - @group.Name.Replace("group.", "") -
    • - } -
    -
  • -
  • -
    - - -
    -
  • -
-
- -
- -
    -
  • -
      - @foreach (var perm in User.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) { -
    • - - - @perm.PermissionName -
    • - } -
    -
  • -
  • -
    - - -
    -
  • -
-
- - - -
-
- -@inject IUserService Users -@inject IPermissionService Permissions -@inject NavigationManager Navigator -@inject SweetAlertService Alerts - -@code { - [Parameter] public string UserId { get; set; } - - private EditContext _context; - private ValidationMessageStore _messages; - - [SupplyParameterFromForm] public User User { get; set; } - - private IList _groups = new List(); - private IList _allGroups = new List(); - private string _selectedGroup; - private string _permissionToAdd; - private string _password; - - protected override async Task OnInitializedAsync() { - if (Guid.TryParse(UserId, out var guid)) { - User = await Users.GetUser(guid); - } - - if (User is null) { - Navigator.NavigateTo("/administration/users"); - } - - _groups = await Permissions.GetUserPermissionGroups(User); - _allGroups = await Permissions.GetPermissionGroups(); - - _context = new EditContext(User); - _context.OnValidationRequested += ValidateForm; - _messages = new ValidationMessageStore(_context); - } - - private async Task OnEdit() { - var hasConflict = false; - - var userByEmail = await Users.GetUserByEmail(User.Email); - if (userByEmail is not null && userByEmail.Id != User.Id) { - _messages.Add(() => User.Email, "Email is already in use"); - hasConflict = true; - } - - var userByUsername = await Users.GetUserByUsername(User.Username); - if (userByUsername is not null && userByUsername.Id != User.Id) { - _messages.Add(() => User.Username, "Username is already in use"); - hasConflict = true; - } - - if (hasConflict) return; - - var result = await Alerts.FireAsync(new SweetAlertOptions { - Title = "Are you sure?", - Icon = SweetAlertIcon.Warning, - ConfirmButtonText = "Yes", - ShowCancelButton = true, - ShowConfirmButton = true - }); - - if (result.IsConfirmed) { - await Users.UpdateUser(User); - - if (!string.IsNullOrWhiteSpace(_password)) { - await Users.ChangePassword(User, _password); - } - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "User edited!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - - Back(); - } - } - - private void Back() { - Navigator.NavigateTo("/administration/users"); - } - - private async Task RemoveGroup(PermissionGroup group) { - var result = await Alerts.FireAsync(new SweetAlertOptions { - Title = "Are you sure?", - Icon = SweetAlertIcon.Warning, - ConfirmButtonText = "Yes", - ShowCancelButton = true, - ShowConfirmButton = true - }); - - if (result.IsConfirmed) { - await Permissions.RemoveGroupFromUser(User, group); - _groups.Remove(group); - StateHasChanged(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Group removed!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - } - - private async Task RemovePermission(Permission perm) { - var result = await Alerts.FireAsync(new SweetAlertOptions { - Title = "Are you sure?", - Icon = SweetAlertIcon.Warning, - ConfirmButtonText = "Yes", - ShowCancelButton = true, - ShowConfirmButton = true - }); - - if (result.IsConfirmed) { - await Permissions.RemovePermission(perm); - User.Permissions.Remove(perm); - StateHasChanged(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Permission removed!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - } - - private async Task AddGroup() { - if (string.IsNullOrWhiteSpace(_selectedGroup)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Select a group!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = true - }); - return; - } - - var group = _allGroups.SingleOrDefault(group => group.Name == _selectedGroup); - - await Permissions.AddPermission(User, group?.Name); - _groups.Add(group); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Group added!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - - private async Task AddPermission() { - if (string.IsNullOrWhiteSpace(_permissionToAdd)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Enter a permission name!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = true - }); - return; - } - - await Permissions.AddPermission(User, _permissionToAdd); - User.Permissions.Add(await Permissions.GetPermission(_permissionToAdd, User)); - _permissionToAdd = ""; - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Permission added!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - - private void ValidateForm(object sender, ValidationRequestedEventArgs e) { - _messages.Clear(); - - if (!User.Email.Contains("@") || !User.Email.Contains(".") || User.Email.EndsWith(".")) { - _messages.Add(() => User.Email, "Please enter a valid email address"); - } - } - - private string ConstructRedirectUrl() { - return "login?redirect=" + Navigator.Uri; - } - -} \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/UsersPage.razor b/HopFrame.Web/Pages/Administration/UsersPage.razor index 1a68fac..2794387 100644 --- a/HopFrame.Web/Pages/Administration/UsersPage.razor +++ b/HopFrame.Web/Pages/Administration/UsersPage.razor @@ -13,13 +13,13 @@ @using Microsoft.AspNetCore.Components.Web @using HopFrame.Web.Components @using BlazorStrap.V5 -@using HopFrame.Web.Model @using HopFrame.Web.Pages.Administration.Components Users - + +

@@ -79,7 +79,7 @@ @if (_hasEditPrivileges) { - Edit + Edit } @if (_hasDeletePrivileges) { @@ -95,7 +95,6 @@ @inject IUserService UserService @inject IPermissionService PermissionsService -@inject NavigationManager Navigator @inject SweetAlertService Alerts @inject ITokenContext Auth @@ -112,6 +111,7 @@ private bool _hasDeletePrivileges = false; private UserAddModal _userAddModal; + private UserEditModal _userEditModal; protected override async Task OnInitializedAsync() { _users = await UserService.GetUsers(); @@ -135,6 +135,9 @@ var groups = await PermissionsService.GetUserPermissionGroups(user); _userGroups.Add(user.Id, groups.FirstOrDefault()); } + + + StateHasChanged(); } private async Task Search() { @@ -191,8 +194,6 @@ if (result.IsConfirmed) { await UserService.DeleteUser(user); await Reload(); - - StateHasChanged(); await Alerts.FireAsync(new SweetAlertOptions { Title = "Deleted!", @@ -203,10 +204,6 @@ } } - private void EditUser(User user) { - Navigator.NavigateTo("/administration/user/" + user.Id); - } - private enum OrderType { None, Email, @@ -218,52 +215,4 @@ Asc = 0, Desc = 1 } - - private async void CreateUser(UserAdd newUser) { - string errorMessage = null; - - if (_users.Any(user => user.Username == newUser.Username)) { - errorMessage = "Username is already taken!"; - } - else if (_users.Any(user => user.Email == newUser.Email)) { - errorMessage = "E-Mail is already taken!"; - } - else if (!newUser.PasswordIsValid) { - errorMessage = "The password needs to be at least 8 characters long!"; - } - else if (!newUser.EmailIsValid) { - errorMessage = "Invalid E-Mail address!"; - } - - if (!string.IsNullOrWhiteSpace(errorMessage)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Something went wrong!", - Text = errorMessage, - Icon = SweetAlertIcon.Error, - ShowConfirmButton = false, - Timer = 1500 - }); - - return; - } - - var user = await UserService.AddUser(newUser); - - if (!string.IsNullOrWhiteSpace(newUser.Group)) { - await PermissionsService.AddPermission(user, newUser.Group); - } - - await Reload(); - - StateHasChanged(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "New user added!", - Icon = SweetAlertIcon.Success, - ShowConfirmButton = false, - Timer = 1500 - - }); - } - } \ No newline at end of file