Converted edit page to modal and added edit and create permissions
This commit is contained in:
@@ -5,4 +5,5 @@ public static class AdminPermissions {
|
|||||||
public const string ViewUsers = "hopframe.admin.users.view";
|
public const string ViewUsers = "hopframe.admin.users.view";
|
||||||
public const string EditUsers = "hopframe.admin.users.edit";
|
public const string EditUsers = "hopframe.admin.users.edit";
|
||||||
public const string DeleteUsers = "hopframe.admin.users.delete";
|
public const string DeleteUsers = "hopframe.admin.users.delete";
|
||||||
|
public const string AddUser = "hopframe.admin.users.add";
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,6 @@ public class RegisterData : UserRegister {
|
|||||||
public string RepeatedPassword { get; set; }
|
public string RepeatedPassword { get; set; }
|
||||||
|
|
||||||
public bool PasswordsMatch => Password == RepeatedPassword;
|
public bool PasswordsMatch => Password == RepeatedPassword;
|
||||||
public bool PasswordIsValid => Password.Length >= 8;
|
public bool PasswordIsValid => Password?.Length >= 8;
|
||||||
public bool EmailIsValid => Email.Contains('@') && Email.Contains('.') && !Email.EndsWith('.');
|
public bool EmailIsValid => Email?.Contains('@') == true && Email?.Contains('.') == true && Email?.EndsWith('.') == false;
|
||||||
}
|
}
|
||||||
@@ -4,31 +4,33 @@
|
|||||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||||
@using BlazorStrap.Shared.Components.Modal
|
@using BlazorStrap.Shared.Components.Modal
|
||||||
@using BlazorStrap.V5
|
@using BlazorStrap.V5
|
||||||
|
@using CurrieTechnologies.Razor.SweetAlert2
|
||||||
@using HopFrame.Database.Models
|
@using HopFrame.Database.Models
|
||||||
|
@using HopFrame.Security.Claims
|
||||||
@using HopFrame.Security.Services
|
@using HopFrame.Security.Services
|
||||||
@using HopFrame.Web.Model
|
@using HopFrame.Web.Model
|
||||||
|
|
||||||
<BSModal DataId="add-user-modal" HideOnValidSubmit="true" IsStaticBackdrop="true" OnShow="() => _user = new()" @ref="_modal" ModalColor="BSColor.Dark">
|
<BSModal DataId="add-user-modal" HideOnValidSubmit="true" IsStaticBackdrop="true" OnShow="() => _user = new()" @ref="_modal">
|
||||||
<BSForm Model="_user" OnValidSubmit="Submit">
|
<BSForm Model="_user" OnValidSubmit="AddUser">
|
||||||
<BSModalHeader style="color: white">Add user</BSModalHeader>
|
<BSModalHeader>Add user</BSModalHeader>
|
||||||
<BSModalContent>
|
<BSModalContent>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<BSLabel style="color: white">E-Mail</BSLabel>
|
<BSLabel>E-Mail</BSLabel>
|
||||||
<BSInput InputType="InputType.Email" @bind-Value="_user.Email" />
|
<BSInput InputType="InputType.Email" @bind-Value="_user.Email" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<BSLabel style="color: white">Username</BSLabel>
|
<BSLabel>Username</BSLabel>
|
||||||
<BSInput InputType="InputType.Text" @bind-Value="_user.Username" />
|
<BSInput InputType="InputType.Text" @bind-Value="_user.Username" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<BSLabel style="color: white">Password</BSLabel>
|
<BSLabel>Password</BSLabel>
|
||||||
<BSInput InputType="InputType.Password" @bind-Value="_user.Password" />
|
<BSInput InputType="InputType.Password" @bind-Value="_user.Password" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<BSLabel style="color: white">Primary group</BSLabel>
|
<BSLabel>Primary group</BSLabel>
|
||||||
<BSInput InputType="InputType.Select" @bind-Value="_user.Group">
|
<BSInput InputType="InputType.Select" @bind-Value="_user.Group">
|
||||||
<option value="">Select group</option>
|
<option value="">Select group</option>
|
||||||
|
|
||||||
@@ -39,31 +41,91 @@
|
|||||||
</div>
|
</div>
|
||||||
</BSModalContent>
|
</BSModalContent>
|
||||||
<BSModalFooter>
|
<BSModalFooter>
|
||||||
<BSButton Target="add-user-modal" Color="BSColor.Dark">Cancel</BSButton>
|
<BSButton Target="add-user-modal">Cancel</BSButton>
|
||||||
<BSButton IsSubmit="true" Color="BSColor.Primary">Save</BSButton>
|
<BSButton IsSubmit="true" Color="BSColor.Primary">Save</BSButton>
|
||||||
</BSModalFooter>
|
</BSModalFooter>
|
||||||
</BSForm>
|
</BSForm>
|
||||||
</BSModal>
|
</BSModal>
|
||||||
|
|
||||||
|
@inject IUserService Users
|
||||||
@inject IPermissionService Permissions
|
@inject IPermissionService Permissions
|
||||||
|
@inject SweetAlertService Alerts
|
||||||
|
@inject ITokenContext Auth
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public Action<UserAdd> OnSubmit { get; set; }
|
[Parameter] public Func<Task> ReloadPage { get; set; }
|
||||||
|
|
||||||
private IList<PermissionGroup> _allGroups = new List<PermissionGroup>();
|
private IList<PermissionGroup> _allGroups = new List<PermissionGroup>();
|
||||||
|
private IList<User> _allUsers = new List<User>();
|
||||||
private UserAdd _user;
|
private UserAdd _user;
|
||||||
|
|
||||||
private BSModalBase _modal;
|
private BSModalBase _modal;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync() {
|
public async Task ShowAsync() {
|
||||||
_allGroups = await Permissions.GetPermissionGroups();
|
_allGroups = await Permissions.GetPermissionGroups();
|
||||||
|
_allUsers = await Users.GetUsers();
|
||||||
|
|
||||||
|
await _modal.ShowAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ShowAsync() {
|
private async Task AddUser() {
|
||||||
return _modal.ShowAsync();
|
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() {
|
if (!string.IsNullOrWhiteSpace(errorMessage)) {
|
||||||
OnSubmit.Invoke(_user);
|
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
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
307
HopFrame.Web/Pages/Administration/Components/UserEditModal.razor
Normal file
307
HopFrame.Web/Pages/Administration/Components/UserEditModal.razor
Normal file
@@ -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
|
||||||
|
|
||||||
|
<BSModal DataId="edit-user-modal" HideOnValidSubmit="true" IsStaticBackdrop="true" @ref="_modal">
|
||||||
|
<BSForm Model="_user" OnValidSubmit="EditUser">
|
||||||
|
<BSModalHeader>Edit @_user.Username</BSModalHeader>
|
||||||
|
<BSModalContent>
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>User id</BSLabel>
|
||||||
|
<input type="text" class="form-control" disabled value="@_user.Id"/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>Created at</BSLabel>
|
||||||
|
<input type="text" class="form-control" disabled value="@_user.CreatedAt"/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>E-Mail</BSLabel>
|
||||||
|
<BSInput InputType="InputType.Email" @bind-Value="_user.Email" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>Username</BSLabel>
|
||||||
|
<BSInput InputType="InputType.Text" @bind-Value="_user.Username" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>Password</BSLabel>
|
||||||
|
<BSInput InputType="InputType.Password" @bind-Value="_newPassword" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>Groups</BSLabel>
|
||||||
|
<BSListGroup>
|
||||||
|
<BSListGroupItem>
|
||||||
|
<BSListGroup IsFlush="true">
|
||||||
|
@foreach (var group in _userGroups) {
|
||||||
|
<BSListGroupItem>
|
||||||
|
<BSButton Color="BSColor.Danger" Size="Size.ExtraSmall" MarginEnd="Margins.Small" OnClick="() => RemoveGroup(group)">
|
||||||
|
<HopIconDisplay Type="HopIconDisplay.HopIcon.Cross"/>
|
||||||
|
</BSButton>
|
||||||
|
|
||||||
|
<span>@group.Name.Replace("group.", "")</span>
|
||||||
|
</BSListGroupItem>
|
||||||
|
}
|
||||||
|
</BSListGroup>
|
||||||
|
</BSListGroupItem>
|
||||||
|
<BSListGroupItem>
|
||||||
|
<div style="display: flex; gap: 20px">
|
||||||
|
<BSInput InputType="InputType.Select" @bind-Value="_selectedGroup">
|
||||||
|
<option selected>Select group</option>
|
||||||
|
|
||||||
|
@foreach (var group in _allGroups) {
|
||||||
|
@if (_userGroups.All(g => g.Name != group.Name)) {
|
||||||
|
<option value="@group.Name">@group.Name.Replace("group.", "")</option>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</BSInput>
|
||||||
|
<BSButton Color="BSColor.Secondary" OnClick="AddGroup">Add</BSButton>
|
||||||
|
</div>
|
||||||
|
</BSListGroupItem>
|
||||||
|
</BSListGroup>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<BSLabel>Permissions</BSLabel>
|
||||||
|
<BSListGroup>
|
||||||
|
<BSListGroupItem>
|
||||||
|
<BSListGroup IsFlush="true">
|
||||||
|
@foreach (var perm in _user.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) {
|
||||||
|
<BSListGroupItem>
|
||||||
|
<BSButton Color="BSColor.Danger" Size="Size.ExtraSmall" MarginEnd="Margins.Small" OnClick="() => RemovePermission(perm)">
|
||||||
|
<HopIconDisplay Type="HopIconDisplay.HopIcon.Cross"/>
|
||||||
|
</BSButton>
|
||||||
|
|
||||||
|
<span>@perm.PermissionName</span>
|
||||||
|
</BSListGroupItem>
|
||||||
|
}
|
||||||
|
</BSListGroup>
|
||||||
|
</BSListGroupItem>
|
||||||
|
<BSListGroupItem>
|
||||||
|
<div style="display: flex; gap: 20px">
|
||||||
|
<BSInput InputType="InputType.Text" @bind-Value="_permissionToAdd"/>
|
||||||
|
<BSButton Color="BSColor.Secondary" OnClick="AddPermission">Add</BSButton>
|
||||||
|
</div>
|
||||||
|
</BSListGroupItem>
|
||||||
|
</BSListGroup>
|
||||||
|
</div>
|
||||||
|
</BSModalContent>
|
||||||
|
<BSModalFooter>
|
||||||
|
<BSButton Target="edit-user-modal">Cancel</BSButton>
|
||||||
|
<BSButton IsSubmit="true" Color="BSColor.Primary">Save</BSButton>
|
||||||
|
</BSModalFooter>
|
||||||
|
</BSForm>
|
||||||
|
</BSModal>
|
||||||
|
|
||||||
|
@inject IUserService Users
|
||||||
|
@inject IPermissionService Permissions
|
||||||
|
@inject SweetAlertService Alerts
|
||||||
|
@inject ITokenContext Auth
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter] public Func<Task> ReloadPage { get; set; }
|
||||||
|
|
||||||
|
private BSModalBase _modal;
|
||||||
|
private User _user;
|
||||||
|
private string _newPassword;
|
||||||
|
|
||||||
|
private IList<PermissionGroup> _userGroups;
|
||||||
|
private IList<PermissionGroup> _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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
|
|
||||||
<PageTitle>Edit @User.Username</PageTitle>
|
|
||||||
<AuthorizedView Permission="@AdminPermissions.EditUsers" RedirectIfUnauthorized="@ConstructRedirectUrl()"/>
|
|
||||||
|
|
||||||
<h3 style="color: white">Edit @User.Username (@User.Id)</h3>
|
|
||||||
|
|
||||||
<EditForm EditContext="_context" OnValidSubmit="OnEdit" FormName="register-form" class="edit-form">
|
|
||||||
@*<AntiforgeryToken />*@
|
|
||||||
<div class="field-wrapper" style="max-width: 750px">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="id" class="form-label" style="color: white">Registered At</label>
|
|
||||||
<input type="text" class="form-control" id="id" disabled value="@User.CreatedAt"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="email" class="form-label" style="color: white">Email address</label>
|
|
||||||
<InputText type="email" class="form-control" id="email" required @bind-Value="User.Email"/>
|
|
||||||
<ValidationMessage For="() => User.Email"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="username" class="form-label" style="color: white">Username</label>
|
|
||||||
<InputText type="text" class="form-control" id="username" required @bind-Value="User.Username"/>
|
|
||||||
<ValidationMessage For="() => User.Username"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="password" class="form-label" style="color: white">Password</label>
|
|
||||||
<InputText type="password" class="form-control" id="password" required @bind-Value="_password"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="groups" class="form-label" style="color: white">Groups</label>
|
|
||||||
<ul class="list-group" id="groups">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<ul class="list-group list-group-flush">
|
|
||||||
@foreach (var group in _groups) {
|
|
||||||
<li class="list-group-item">
|
|
||||||
<button type="button" class="btn btn-danger btn-sm" style="margin-right: 15px" @onclick="() => RemoveGroup(group)">
|
|
||||||
<HopIconDisplay Type="HopIconDisplay.HopIcon.Cross"/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<span>@group.Name.Replace("group.", "")</span>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<div style="display: flex; gap: 20px">
|
|
||||||
<select class="form-select" aria-label="Add group to user" id="add-group" @bind="_selectedGroup">
|
|
||||||
<option selected>Select group</option>
|
|
||||||
|
|
||||||
@foreach (var group in _allGroups) {
|
|
||||||
if (_groups.All(g => g.Name != group.Name)) {
|
|
||||||
<option value="@group.Name">@group.Name.Replace("group.", "")</option>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
<button type="button" class="btn btn-secondary" @onclick="AddGroup">Add</button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="permissions" class="form-label" style="color: white">Permissions</label>
|
|
||||||
<ul class="list-group" id="permissions">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<ul class="list-group list-group-flush">
|
|
||||||
@foreach (var perm in User.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) {
|
|
||||||
<li class="list-group-item">
|
|
||||||
<button type="button" class="btn btn-danger btn-sm" style="margin-right: 15px" @onclick="() => RemovePermission(perm)">
|
|
||||||
<HopIconDisplay Type="HopIconDisplay.HopIcon.Cross"/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<span>@perm.PermissionName</span>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item">
|
|
||||||
<div style="display: flex; gap: 20px">
|
|
||||||
<input type="text" class="form-control" placeholder="New permission" @bind="_permissionToAdd">
|
|
||||||
<button type="button" class="btn btn-secondary" @onclick="AddPermission">Add</button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Edit</button>
|
|
||||||
<button type="reset" class="btn btn-secondary" @onclick="Back">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
|
|
||||||
@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<PermissionGroup> _groups = new List<PermissionGroup>();
|
|
||||||
private IList<PermissionGroup> _allGroups = new List<PermissionGroup>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
@using Microsoft.AspNetCore.Components.Web
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
@using HopFrame.Web.Components
|
@using HopFrame.Web.Components
|
||||||
@using BlazorStrap.V5
|
@using BlazorStrap.V5
|
||||||
@using HopFrame.Web.Model
|
|
||||||
@using HopFrame.Web.Pages.Administration.Components
|
@using HopFrame.Web.Pages.Administration.Components
|
||||||
|
|
||||||
<PageTitle>Users</PageTitle>
|
<PageTitle>Users</PageTitle>
|
||||||
<AuthorizedView Permission="@AdminPermissions.ViewUsers" RedirectIfUnauthorized="login?redirect=/administration/users"/>
|
<AuthorizedView Permission="@AdminPermissions.ViewUsers" RedirectIfUnauthorized="login?redirect=/administration/users"/>
|
||||||
|
|
||||||
<UserAddModal @ref="_userAddModal" OnSubmit="CreateUser"/>
|
<UserAddModal @ref="_userAddModal" ReloadPage="Reload"/>
|
||||||
|
<UserEditModal @ref="_userEditModal" ReloadPage="Reload"/>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h3>
|
<h3>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<BSTD>
|
<BSTD>
|
||||||
<BSButtonGroup>
|
<BSButtonGroup>
|
||||||
@if (_hasEditPrivileges) {
|
@if (_hasEditPrivileges) {
|
||||||
<BSButton Color="BSColor.Warning" OnClick="() => EditUser(user)">Edit</BSButton>
|
<BSButton Color="BSColor.Warning" OnClick="() => _userEditModal.ShowAsync(user)">Edit</BSButton>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_hasDeletePrivileges) {
|
@if (_hasDeletePrivileges) {
|
||||||
@@ -95,7 +95,6 @@
|
|||||||
|
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IPermissionService PermissionsService
|
@inject IPermissionService PermissionsService
|
||||||
@inject NavigationManager Navigator
|
|
||||||
@inject SweetAlertService Alerts
|
@inject SweetAlertService Alerts
|
||||||
@inject ITokenContext Auth
|
@inject ITokenContext Auth
|
||||||
|
|
||||||
@@ -112,6 +111,7 @@
|
|||||||
private bool _hasDeletePrivileges = false;
|
private bool _hasDeletePrivileges = false;
|
||||||
|
|
||||||
private UserAddModal _userAddModal;
|
private UserAddModal _userAddModal;
|
||||||
|
private UserEditModal _userEditModal;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync() {
|
protected override async Task OnInitializedAsync() {
|
||||||
_users = await UserService.GetUsers();
|
_users = await UserService.GetUsers();
|
||||||
@@ -135,6 +135,9 @@
|
|||||||
var groups = await PermissionsService.GetUserPermissionGroups(user);
|
var groups = await PermissionsService.GetUserPermissionGroups(user);
|
||||||
_userGroups.Add(user.Id, groups.FirstOrDefault());
|
_userGroups.Add(user.Id, groups.FirstOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Search() {
|
private async Task Search() {
|
||||||
@@ -191,8 +194,6 @@
|
|||||||
if (result.IsConfirmed) {
|
if (result.IsConfirmed) {
|
||||||
await UserService.DeleteUser(user);
|
await UserService.DeleteUser(user);
|
||||||
await Reload();
|
await Reload();
|
||||||
|
|
||||||
StateHasChanged();
|
|
||||||
|
|
||||||
await Alerts.FireAsync(new SweetAlertOptions {
|
await Alerts.FireAsync(new SweetAlertOptions {
|
||||||
Title = "Deleted!",
|
Title = "Deleted!",
|
||||||
@@ -203,10 +204,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditUser(User user) {
|
|
||||||
Navigator.NavigateTo("/administration/user/" + user.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum OrderType {
|
private enum OrderType {
|
||||||
None,
|
None,
|
||||||
Email,
|
Email,
|
||||||
@@ -218,52 +215,4 @@
|
|||||||
Asc = 0,
|
Asc = 0,
|
||||||
Desc = 1
|
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
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user