diff --git a/src/HopFrame.Web.Admin/Generators/IAdminContextGenerator.cs b/src/HopFrame.Web.Admin/Generators/IAdminContextGenerator.cs index 49cf115..970d82c 100644 --- a/src/HopFrame.Web.Admin/Generators/IAdminContextGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IAdminContextGenerator.cs @@ -2,6 +2,11 @@ namespace HopFrame.Web.Admin.Generators; public interface IAdminContextGenerator { + /// + /// Returns the generator object for the specified Admin Page. This needs to be within the same Admin Context. + /// + /// The Model of the Admin Page + /// IAdminPageGenerator Page(); } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs b/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs index 12591bb..2a71a75 100644 --- a/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs @@ -5,24 +5,105 @@ namespace HopFrame.Web.Admin.Generators; public interface IAdminPageGenerator { + /// + /// Sets the title of the Admin Page + /// + /// the specified title + /// IAdminPageGenerator Title(string title); + + /// + /// Sets the description of the Admin Page + /// + /// the specified description + /// IAdminPageGenerator Description(string description); + + /// + /// Sets the url for the Admin Page + /// + /// the specified url (administration/{url}) + /// IAdminPageGenerator Url(string url); + /// + /// Sets the permission needed to view the Admin Page + /// + /// the specified permission + /// IAdminPageGenerator ViewPermission(string permission); + + /// + /// Sets the permission needed to create a new Entry + /// + /// the specified permission + /// IAdminPageGenerator CreatePermission(string permission); + + /// + /// Sets the permission needed to update an Entry + /// + /// the specified permission + /// IAdminPageGenerator UpdatePermission(string permission); + + /// + /// Sets the permission needed to delete an Entry + /// + /// the specified permission + /// IAdminPageGenerator DeletePermission(string permission); + + /// + /// Enables or disables the create button + /// + /// the specified state + /// IAdminPageGenerator ShowCreateButton(bool show); + + /// + /// Enables or disables the delete button + /// + /// the specified state + /// IAdminPageGenerator ShowDeleteButton(bool show); + + /// + /// Enables or disables the update button + /// + /// the specified state + /// IAdminPageGenerator ShowUpdateButton(bool show); + /// + /// Specifies the default sort property and direction + /// + /// Which property should be sorted + /// In which direction should be sorted + /// IAdminPageGenerator DefaultSort(Expression> propertyExpression, ListSortDirection direction); + /// + /// Specifies the repository for the page + /// + /// The specified repository + /// IAdminPageGenerator ConfigureRepository() where TRepository : ModelRepository; + + /// + /// Returns the generator of the specified property + /// + /// The property + /// IAdminPropertyGenerator Property(Expression> propertyExpression); + + /// + /// Specifies the default property that should be displayed as a property in other listings + /// + /// The property + /// IAdminPageGenerator ListingProperty(Expression> propertyExpression); } diff --git a/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs b/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs index 7f138bb..4fbab5b 100644 --- a/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs @@ -4,25 +4,120 @@ namespace HopFrame.Web.Admin.Generators; public interface IAdminPropertyGenerator { + /// + /// Should the property be sortable or not + /// + /// IAdminPropertyGenerator Sortable(bool sortable); + + /// + /// Should the admin be able to edit the property after creation or not + /// + /// IAdminPropertyGenerator Editable(bool editable); + + /// + /// Should the value of the property be displayed while editing or not (useful for passwords and tokens) + /// + /// IAdminPropertyGenerator DisplayValueWhileEditing(bool display); + + /// + /// Should the property be a column on the page list or not + /// + /// IAdminPropertyGenerator DisplayInListing(bool display = true); + + /// + /// Should the property be ignored completely + /// + /// IAdminPropertyGenerator Ignore(bool ignore = true); + + /// + /// Is the value of the property database generated and is not meant to be changed + /// + /// IAdminPropertyGenerator Generated(bool generated = true); + + /// + /// Should the property value be bold in the listing or not + /// + /// IAdminPropertyGenerator Bold(bool bold = true); + + /// + /// Is the value of the property unique under all other entries in the dataset + /// + /// + /// IAdminPropertyGenerator Unique(bool unique = true); + /// + /// Specifies the display name in the listing and editing/creation + /// + /// IAdminPropertyGenerator DisplayName(string displayName); - IAdminPropertyGenerator Description(string description); + + /// + /// Has the value of the property a never changing prefix that doesn't need to be specified or displayed + /// + /// IAdminPropertyGenerator Prefix(string prefix); + + /// + /// The specified function gets called before creation/edit to verify that the entered value matches the property requirements + /// + /// IAdminPropertyGenerator Validator(Func validator); + + /// + /// Sets the input type in creation/edit to a selector for the property type. The property type needs to have its own admin page in order for the selector to work! + /// + /// IAdminPropertyGenerator IsSelector(bool selector = true); + + /// + /// Sets the input type in creation/edit to a selector for the specified type. The specified type needs to have its own admin page in order for the selector to work! + /// + /// + /// + /// IAdminPropertyGenerator IsSelector(bool selector = true); + + /// + /// The specified function gets called, whenever the entry is changed/created in order to convert the raw string input to the proper property type + /// + /// IAdminPropertyGenerator Parser(Func parser); + + /// + /// The specified function gets called, whenever the entry is changed/created in order to convert the raw string input to the proper property type + /// + /// Needs to be specified if the field is not a plain string field (like a selector with a different type) + /// IAdminPropertyGenerator Parser(Func parser); + + /// + /// The specified function gets called, whenever the entry is changed/created in order to convert the raw string input to the proper property type + /// + /// Needs to be specified if the field is not a plain string field (like a selector with a different type) + /// Needs to be specified if the property type is a List + /// IAdminPropertyGenerator Parser(Func parser); + + /// + /// Specifies the default property that should be displayed as a value + /// + /// + /// IAdminPropertyGenerator DisplayProperty(Expression> propertyExpression); + + /// + /// Specifies the default property that should be displayed as a value + /// + /// Needs to be specified if the property type is a List + /// IAdminPropertyGenerator DisplayProperty(Expression> propertyExpression); } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/IGenerator.cs b/src/HopFrame.Web.Admin/Generators/IGenerator.cs index 5cf9d6f..68f5013 100644 --- a/src/HopFrame.Web.Admin/Generators/IGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IGenerator.cs @@ -2,6 +2,10 @@ namespace HopFrame.Web.Admin.Generators; public interface IGenerator { + /// + /// Compiles the generator with all specified options + /// + /// The compiled data structure TGeneratedType Compile(); } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs index 73767a6..d6a5792 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs @@ -61,11 +61,6 @@ internal sealed class AdminPropertyGenerator(string name, Typ return this; } - public IAdminPropertyGenerator Description(string description) { - _property.Description = description; - return this; - } - public IAdminPropertyGenerator Prefix(string prefix) { _property.Prefix = prefix; return this; @@ -152,11 +147,6 @@ internal sealed class AdminPropertyGenerator(string name, Typ var attribute = attributes.Single(a => a is AdminNameAttribute) as AdminNameAttribute; DisplayName(attribute?.Name); } - - if (attributes.Any(a => a is AdminDescriptionAttribute)) { - var attribute = attributes.Single(a => a is AdminDescriptionAttribute) as AdminDescriptionAttribute; - Description(attribute?.Description); - } if (attributes.Any(a => a is AdminBoldAttribute)) { var attribute = attributes.Single(a => a is AdminBoldAttribute) as AdminBoldAttribute; diff --git a/src/HopFrame.Web.Admin/Models/AdminPage.cs b/src/HopFrame.Web.Admin/Models/AdminPage.cs index eedd4a5..748eb00 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPage.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPage.cs @@ -13,9 +13,8 @@ public class AdminPage { public IList Properties { get; set; } public string ListingProperty { get; set; } - [JsonIgnore] public Type RepositoryProvider { get; set; } - + public Type ModelType { get; set; } public string DefaultSortPropertyName { get; set; } diff --git a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs index a86cf47..8347e36 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs @@ -5,7 +5,6 @@ namespace HopFrame.Web.Admin.Models; public sealed class AdminPageProperty { public string Name { get; set; } public string DisplayName { get; set; } - public string Description { get; set; } public string Prefix { get; set; } public string DisplayPropertyName { get; set; } @@ -21,7 +20,6 @@ public sealed class AdminPageProperty { public bool Selector { get; set; } public Type SelectorType { get; set; } - [JsonIgnore] public Type Type { get; set; } public Func Validator { get; set; } diff --git a/src/HopFrame.Web/Components/Administration/GroupAddModal.razor b/src/HopFrame.Web/Components/Administration/GroupAddModal.razor deleted file mode 100644 index 8f432e7..0000000 --- a/src/HopFrame.Web/Components/Administration/GroupAddModal.razor +++ /dev/null @@ -1,292 +0,0 @@ -@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.Database.Repositories -@using HopFrame.Security.Claims -@using HopFrame.Web.Model - - - - @if (_isEdit) { - Edit group - } - else { - Add group - } - -
- Name - @if (!_isEdit) { - - group. - - - } - else { - - } -
- - @if (_isEdit) { -
- Created at - -
- } - -
- Description - -
- -
- - Default group - -
- -
- Inherits from - - - - @foreach (var group in _group.Permissions.Where(g => g.PermissionName.StartsWith("group."))) { - - - - - - @group.PermissionName.Replace("group.", "") - - } - - - -
- - - - @foreach (var group in _allGroups) { - @if (_group.Permissions.All(g => g.PermissionName != group.Name) && group.Name != _group.Name) { - - } - } - - Add -
-
-
-
- -
- Permissions - - - - @foreach (var perm in _group.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) { - - - - - - @perm.PermissionName - - } - - - -
- - Add -
-
-
-
-
- - Cancel - Save - -
-
- -@inject IGroupRepository Groups -@inject IPermissionRepository Permissions -@inject SweetAlertService Alerts -@inject ITokenContext Context - -@code { - [Parameter] public Func ReloadPage { get; set; } - - private PermissionGroupAdd _group; - - private BSModalBase _modal; - private string _permissionToAdd; - private string _groupToAdd; - - private IList _allGroups; - - private bool _isEdit; - - public async Task ShowAsync(PermissionGroup group = null) { - _allGroups = await Groups.GetPermissionGroups(); - - if (group is not null) { - _group = new PermissionGroupAdd { - CreatedAt = group.CreatedAt, - Description = group.Description, - Name = group.Name, - IsDefaultGroup = group.IsDefaultGroup, - Permissions = group.Permissions - }; - _isEdit = true; - } - else { - _group = new PermissionGroupAdd { - Permissions = new List(), - IsDefaultGroup = false - }; - _isEdit = false; - } - - await _modal.ShowAsync(); - } - - private async Task AddPermission() { - if (string.IsNullOrWhiteSpace(_permissionToAdd)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Enter a permission name!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = true - }); - return; - } - - if (_isEdit) { - if (!await Permissions.HasPermission(Context.User, Security.AdminPermissions.EditGroup)) { - await NoEditPermissions(); - return; - } - - await Permissions.AddPermission(_group, _permissionToAdd); - } - - _group.Permissions.Add(new Permission { - PermissionName = _permissionToAdd, - GrantedAt = DateTime.Now - }); - - _permissionToAdd = null; - } - - private async Task RemovePermission(Permission permission) { - if (_isEdit) { - await Permissions.RemovePermission(_group, permission.PermissionName); - } - - _group.Permissions.Remove(permission); - } - - private async Task AddInheritanceGroup() { - if (string.IsNullOrWhiteSpace(_groupToAdd)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Select a group!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = true - }); - return; - } - - if (_isEdit) { - if (!await Permissions.HasPermission(Context.User, Security.AdminPermissions.EditGroup)) { - await NoEditPermissions(); - return; - } - - await Permissions.AddPermission(_group, _groupToAdd); - } - - _group.Permissions.Add(new Permission { - PermissionName = _groupToAdd - }); - - _groupToAdd = null; - } - - private async Task AddGroup() { - if (_isEdit) { - if (!await Permissions.HasPermission(Context.User, Security.AdminPermissions.EditGroup)) { - await NoEditPermissions(); - return; - } - - await Groups.EditPermissionGroup(_group); - - if (ReloadPage is not null) - await ReloadPage.Invoke(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Group edited!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - - return; - } - - if (!await Permissions.HasPermission(Context.User, Security.AdminPermissions.AddGroup)) { - await NoAddPermissions(); - return; - } - - if (_allGroups.Any(group => group.Name == _group.Name)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Something went wrong!", - Text = "This group already exists!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = false, - Timer = 1500 - }); - return; - } - - await Groups.CreatePermissionGroup(new PermissionGroup { - Description = _group.Description, - IsDefaultGroup = _group.IsDefaultGroup, - Permissions = _group.Permissions, - Name = "group." + _group.GroupName - }); - - if (ReloadPage is not null) - await ReloadPage.Invoke(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Group added!", - 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 group!", - Icon = SweetAlertIcon.Error - }); - } - - private async Task NoAddPermissions() { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Unauthorized!", - Text = "You don't have the required permissions to add a group!", - Icon = SweetAlertIcon.Error - }); - } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Components/Administration/UserAddModal.razor b/src/HopFrame.Web/Components/Administration/UserAddModal.razor deleted file mode 100644 index 44b47b3..0000000 --- a/src/HopFrame.Web/Components/Administration/UserAddModal.razor +++ /dev/null @@ -1,136 +0,0 @@ -@rendermode InteractiveServer - -@using BlazorStrap -@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.Database.Repositories -@using HopFrame.Security.Claims -@using HopFrame.Web.Model - - - - Add user - -
- E-Mail - -
- -
- Username - -
- -
- Password - -
- -
- Primary group - - - - @foreach (var group in _allGroups) { - - } - -
-
- - Cancel - Save - -
-
- -@inject IUserRepository Users -@inject IPermissionRepository Permissions -@inject IGroupRepository Groups -@inject SweetAlertService Alerts -@inject ITokenContext Auth - -@code { - [Parameter] public Func ReloadPage { get; set; } - - private IList _allGroups = new List(); - private IList _allUsers = new List(); - private UserAdd _user; - - private BSModalBase _modal; - - public async Task ShowAsync() { - _allGroups = await Groups.GetPermissionGroups(); - _allUsers = await Users.GetUsers(); - - await _modal.ShowAsync(); - } - - private async Task AddUser() { - if (!(await Permissions.HasPermission(Auth.User, Security.AdminPermissions.AddUser))) { - 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!"; - } - - 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(new User { - Username = _user.Username, - Email = _user.Email, - Password = _user.Password - }); - - 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 add a user!", - Icon = SweetAlertIcon.Error - }); - } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Components/Administration/UserEditModal.razor b/src/HopFrame.Web/Components/Administration/UserEditModal.razor deleted file mode 100644 index f4bbe36..0000000 --- a/src/HopFrame.Web/Components/Administration/UserEditModal.razor +++ /dev/null @@ -1,306 +0,0 @@ -@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.Database.Repositories -@using HopFrame.Security.Claims -@using HopFrame.Web.Model - - - - 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) == true) { - - } - } - - Add -
-
-
-
- -
- Permissions - - - - @foreach (var perm in _user.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) { - - - - - - @perm.PermissionName - - } - - - -
- - Add -
-
-
-
-
- - Cancel - Save - -
-
- -@inject IUserRepository Users -@inject IPermissionRepository Permissions -@inject IGroupRepository Groups -@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(Auth.User, Security.AdminPermissions.EditUser)) { - await NoEditPermissions(); - return; - } - - _user = user; - _userGroups = await Groups.GetUserGroups(user); - _allGroups = await Groups.GetPermissionGroups(); - await _modal.ShowAsync(); - } - - private async Task AddGroup() { - if (!await Permissions.HasPermission(Auth.User, Security.AdminPermissions.EditUser)) { - 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(Auth.User, Security.AdminPermissions.EditUser)) { - 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(_user, group.Name); - _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(Auth.User, Security.AdminPermissions.EditUser)) { - await NoEditPermissions(); - return; - } - - if (string.IsNullOrWhiteSpace(_permissionToAdd)) { - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Enter a permission name!", - Icon = SweetAlertIcon.Error, - ShowConfirmButton = true - }); - return; - } - - _user.Permissions.Add(await Permissions.AddPermission(_user, _permissionToAdd)); - _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(Auth.User, Security.AdminPermissions.EditUser)) { - 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, perm.PermissionName); - _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(Auth.User, Security.AdminPermissions.EditUser)) { - 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/src/HopFrame.Web/Model/NavigationItem.cs b/src/HopFrame.Web/Model/NavigationItem.cs deleted file mode 100644 index 6e255a0..0000000 --- a/src/HopFrame.Web/Model/NavigationItem.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace HopFrame.Web.Model; - -public sealed class NavigationItem { - public string Name { get; set; } - public string Url { get; set; } - public string Permission { get; set; } - public string Description { get; set; } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Model/PermissionGroupAdd.cs b/src/HopFrame.Web/Model/PermissionGroupAdd.cs deleted file mode 100644 index 0cdc9d2..0000000 --- a/src/HopFrame.Web/Model/PermissionGroupAdd.cs +++ /dev/null @@ -1,7 +0,0 @@ -using HopFrame.Database.Models; - -namespace HopFrame.Web.Model; - -internal sealed class PermissionGroupAdd : PermissionGroup { - public string GroupName { get; set; } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Model/RegisterData.cs b/src/HopFrame.Web/Model/RegisterData.cs deleted file mode 100644 index 6d92531..0000000 --- a/src/HopFrame.Web/Model/RegisterData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using HopFrame.Security.Models; - -namespace HopFrame.Web.Model; - -internal class RegisterData : UserRegister { - public string RepeatedPassword { get; set; } - - public bool PasswordsMatch => Password == RepeatedPassword; - 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/src/HopFrame.Web/Model/UserAdd.cs b/src/HopFrame.Web/Model/UserAdd.cs deleted file mode 100644 index e138395..0000000 --- a/src/HopFrame.Web/Model/UserAdd.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace HopFrame.Web.Model; - -internal sealed class UserAdd : RegisterData { - public string Group { get; set; } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Pages/Administration/GroupsPage.razor b/src/HopFrame.Web/Pages/Administration/GroupsPage.razor deleted file mode 100644 index 42269da..0000000 --- a/src/HopFrame.Web/Pages/Administration/GroupsPage.razor +++ /dev/null @@ -1,192 +0,0 @@ -@page "/administration/group" -@rendermode InteractiveServer -@layout AdminLayout - -@using System.Globalization -@using static Microsoft.AspNetCore.Components.Web.RenderMode -@using BlazorStrap -@using Microsoft.AspNetCore.Components.Web -@using HopFrame.Web.Components -@using HopFrame.Web.Components.Administration -@using BlazorStrap.V5 -@using CurrieTechnologies.Razor.SweetAlert2 -@using HopFrame.Database.Models -@using HopFrame.Database.Repositories -@using HopFrame.Security.Claims -@using HopFrame.Web.Pages.Administration.Layout - -Groups - - - - -
-

- Groups administration - - - -

- - - - Add Group - -
- - - - - - Name - @if (_currentOrder == OrderType.Name) { - - } - - Description - Default - - Created - @if (_currentOrder == OrderType.Created) { - - } - - - @if (_hasEditPrivileges || _hasDeletePrivileges) { - Actions - } - - - - - @foreach (var group in _groups) { - - @group.Name.Replace("group.", "") - @group.Description - - @if (group.IsDefaultGroup) { - Yes - } - else { - No - } - - @group.CreatedAt - - @if (_hasEditPrivileges || _hasDeletePrivileges) { - - - @if (_hasEditPrivileges) { - Edit - } - - @if (_hasDeletePrivileges) { - Delete - } - - - } - - } - - - -@inject IGroupRepository Groups -@inject IPermissionRepository Permissions -@inject ITokenContext Auth -@inject SweetAlertService Alerts - -@code { - private IList _groups = new List(); - - private bool _hasEditPrivileges = false; - private bool _hasDeletePrivileges = false; - private string _searchText; - private OrderType _currentOrder = OrderType.None; - private OrderDirection _currentOrderDirection = OrderDirection.Asc; - - private GroupAddModal _groupAddModal; - - protected override async Task OnInitializedAsync() { - _groups = await Groups.GetPermissionGroups(); - - _hasEditPrivileges = await Permissions.HasPermission(Auth.User, Security.AdminPermissions.EditGroup); - _hasDeletePrivileges = await Permissions.HasPermission(Auth.User, Security.AdminPermissions.DeleteGroup); - } - - private async Task Reload() { - _groups = new List(); - - _groups = await Groups.GetPermissionGroups(); - - OrderBy(_currentOrder, false); - StateHasChanged(); - } - - private async Task Search() { - var groups = await Groups.GetPermissionGroups(); - - if (!string.IsNullOrWhiteSpace(_searchText)) { - groups = groups - .Where(group => group.Name.Contains(_searchText) || - group.Description?.Contains(_searchText) == true || - group.CreatedAt.ToString(CultureInfo.InvariantCulture).Contains(_searchText) || - group.Permissions.Any(perm => perm.PermissionName.Contains(_searchText))) - .ToList(); - } - - _groups = groups; - OrderBy(_currentOrder, false); - } - - private void OrderBy(OrderType type, bool changeDir = true) { - if (_currentOrder == type && changeDir) _currentOrderDirection = (OrderDirection)(((byte)_currentOrderDirection + 1) % 2); - if (_currentOrder != type) _currentOrderDirection = OrderDirection.Asc; - - if (type == OrderType.Name) { - _groups = _currentOrderDirection == OrderDirection.Asc ? _groups.OrderBy(group => group.Name).ToList() : _groups.OrderByDescending(group => group.Name).ToList(); - } - else if (type == OrderType.Created) { - _groups = _currentOrderDirection == OrderDirection.Asc ? _groups.OrderBy(group => group.CreatedAt).ToList() : _groups.OrderByDescending(group => group.CreatedAt).ToList(); - } - - _currentOrder = type; - } - - private async Task Delete(PermissionGroup group) { - var result = await Alerts.FireAsync(new SweetAlertOptions { - Title = "Are you sure?", - Text = "You won't be able to revert this!", - Icon = SweetAlertIcon.Warning, - ConfirmButtonText = "Yes", - ShowCancelButton = true, - ShowConfirmButton = true - }); - - if (result.IsConfirmed) { - await Groups.DeletePermissionGroup(group); - await Reload(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Deleted!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - } - - private enum OrderType { - None, - Name, - Created - } - - private enum OrderDirection : byte { - Asc = 0, - Desc = 1 - } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Pages/Administration/GroupsPage.razor.css b/src/HopFrame.Web/Pages/Administration/GroupsPage.razor.css deleted file mode 100644 index 445d132..0000000 --- a/src/HopFrame.Web/Pages/Administration/GroupsPage.razor.css +++ /dev/null @@ -1,26 +0,0 @@ -.title { - display: flex; - flex-direction: row; - gap: 10px; - margin-bottom: 10px; -} - -#search { - margin-left: auto; -} - -th, h3 { - user-select: none; -} - -h3 { - color: white; -} - -.reload, .sorter { - cursor: pointer; -} - -.bold { - font-weight: bold; -} diff --git a/src/HopFrame.Web/Pages/Administration/UsersPage.razor b/src/HopFrame.Web/Pages/Administration/UsersPage.razor deleted file mode 100644 index 767dc98..0000000 --- a/src/HopFrame.Web/Pages/Administration/UsersPage.razor +++ /dev/null @@ -1,222 +0,0 @@ -@page "/administration/user" -@rendermode InteractiveServer -@layout AdminLayout - -@using System.Globalization -@using BlazorStrap -@using CurrieTechnologies.Razor.SweetAlert2 -@using HopFrame.Database.Models -@using HopFrame.Security.Claims -@using HopFrame.Web.Pages.Administration.Layout -@using static Microsoft.AspNetCore.Components.Web.RenderMode -@using Microsoft.AspNetCore.Components.Web -@using HopFrame.Web.Components -@using BlazorStrap.V5 -@using HopFrame.Database.Repositories -@using HopFrame.Web.Components.Administration - -Users - - - - - -
-

- Users administration - - - -

- - - - Add User - -
- - - - - # - - E-Mail - @if (_currentOrder == OrderType.Email) { - - } - - - Username - @if (_currentOrder == OrderType.Username) { - - } - - - Registered - @if (_currentOrder == OrderType.Registered) { - - } - - Primary Group - - @if (_hasEditPrivileges || _hasDeletePrivileges) { - Actions - } - - - - - @foreach (var user in _users) { - - @user.Id - @user.Email - @user.Username - @user.CreatedAt - @GetFriendlyGroupName(user) - - @if (_hasEditPrivileges || _hasDeletePrivileges) { - - - @if (_hasEditPrivileges) { - Edit - } - - @if (_hasDeletePrivileges) { - Delete - } - - - } - - } - - - -@inject IUserRepository UserService -@inject IPermissionRepository PermissionsService -@inject IGroupRepository Groups -@inject SweetAlertService Alerts -@inject ITokenContext Auth - -@code { - private IList _users = new List(); - private IDictionary _userGroups = new Dictionary(); - - private OrderType _currentOrder = OrderType.None; - private OrderDirection _currentOrderDirection = OrderDirection.Asc; - - private string _searchText; - - private bool _hasEditPrivileges = false; - private bool _hasDeletePrivileges = false; - - private UserAddModal _userAddModal; - private UserEditModal _userEditModal; - - protected override async Task OnInitializedAsync() { - _users = await UserService.GetUsers(); - - foreach (var user in _users) { - var groups = await Groups.GetUserGroups(user); - _userGroups.Add(user.Id, groups.LastOrDefault()); - } - - _hasEditPrivileges = await PermissionsService.HasPermission(Auth.User, Security.AdminPermissions.EditUser); - _hasDeletePrivileges = await PermissionsService.HasPermission(Auth.User, Security.AdminPermissions.DeleteUser); - } - - private async Task Reload() { - _users = new List(); - _userGroups = new Dictionary(); - - _users = await UserService.GetUsers(); - - foreach (var user in _users) { - var groups = await Groups.GetUserGroups(user); - _userGroups.Add(user.Id, groups.LastOrDefault()); - } - - OrderBy(_currentOrder, false); - StateHasChanged(); - } - - private async Task Search() { - var users = await UserService.GetUsers(); - - if (!string.IsNullOrWhiteSpace(_searchText)) { - users = users - .Where(user => - user.Email.Contains(_searchText) || - user.Username.Contains(_searchText) || - user.Id.ToString().Contains(_searchText) || - user.CreatedAt.ToString(CultureInfo.InvariantCulture).Contains(_searchText) || - _userGroups[user.Id]?.Name.Contains(_searchText) == true) - .ToList(); - } - - _users = users; - OrderBy(_currentOrder, false); - } - - private string GetFriendlyGroupName(User user) { - var group = _userGroups[user.Id]; - if (group is null) return null; - - return group.Name.Replace("group.", ""); - } - - private void OrderBy(OrderType type, bool changeDir = true) { - if (_currentOrder == type && changeDir) _currentOrderDirection = (OrderDirection)(((byte)_currentOrderDirection + 1) % 2); - if (_currentOrder != type) _currentOrderDirection = OrderDirection.Asc; - - if (type == OrderType.Email) { - _users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.Email).ToList() : _users.OrderByDescending(user => user.Email).ToList(); - } - else if (type == OrderType.Username) { - _users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.Username).ToList() : _users.OrderByDescending(user => user.Username).ToList(); - } - else if (type == OrderType.Registered) { - _users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.CreatedAt).ToList() : _users.OrderByDescending(user => user.CreatedAt).ToList(); - } - - _currentOrder = type; - } - - private async Task Delete(User user) { - var result = await Alerts.FireAsync(new SweetAlertOptions { - Title = "Are you sure?", - Text = "You won't be able to revert this!", - Icon = SweetAlertIcon.Warning, - ConfirmButtonText = "Yes", - ShowCancelButton = true, - ShowConfirmButton = true - }); - - if (result.IsConfirmed) { - await UserService.DeleteUser(user); - await Reload(); - - await Alerts.FireAsync(new SweetAlertOptions { - Title = "Deleted!", - Icon = SweetAlertIcon.Success, - Timer = 1500, - ShowConfirmButton = false - }); - } - } - - private enum OrderType { - None, - Email, - Username, - Registered - } - - private enum OrderDirection : byte { - Asc = 0, - Desc = 1 - } -} \ No newline at end of file diff --git a/src/HopFrame.Web/Pages/Administration/UsersPage.razor.css b/src/HopFrame.Web/Pages/Administration/UsersPage.razor.css deleted file mode 100644 index 445d132..0000000 --- a/src/HopFrame.Web/Pages/Administration/UsersPage.razor.css +++ /dev/null @@ -1,26 +0,0 @@ -.title { - display: flex; - flex-direction: row; - gap: 10px; - margin-bottom: 10px; -} - -#search { - margin-left: auto; -} - -th, h3 { - user-select: none; -} - -h3 { - color: white; -} - -.reload, .sorter { - cursor: pointer; -} - -.bold { - font-weight: bold; -}