From 724bb95809bf704bda66d904a9d0b4fb8dc979f7 Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Fri, 17 Oct 2025 18:31:07 +0200 Subject: [PATCH 1/4] Added role based authorization base --- src/Controllers/HomeController.cs | 13 ++++++++ src/Controllers/UsersController.cs | 48 ++++++++++++++++++++++++++++-- src/Models/UserModels.cs | 4 ++- src/Models/UsersRequestModels.cs | 12 ++++++++ src/Services/LdapService.cs | 2 +- 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/Controllers/HomeController.cs b/src/Controllers/HomeController.cs index cfd5b81..caf93b0 100644 --- a/src/Controllers/HomeController.cs +++ b/src/Controllers/HomeController.cs @@ -113,6 +113,19 @@ public class HomeController : Controller [ new(ClaimTypes.Name, username) ]; + HashSet roles = []; + foreach (string groupCn in authenticationResult.UserModel?.Description?.Groups ?? []) + { + GroupModel group = await _ldap.GetGroupByCnAsync(groupCn, _ldap.GroupsAttributes); + foreach (GroupPermission permission in group.Permissions) + { + roles.Add(permission.ToString()); + } + } + foreach (string role in roles) + { + claims.Add(new(ClaimTypes.Role, role)); + } var claimsIdentity = new ClaimsIdentity( claims, diff --git a/src/Controllers/UsersController.cs b/src/Controllers/UsersController.cs index 6de8a0e..1e9070e 100644 --- a/src/Controllers/UsersController.cs +++ b/src/Controllers/UsersController.cs @@ -7,6 +7,7 @@ using Berufsschule_HAM.Helpers; using System.Security.Cryptography; using System.Text; using Microsoft.AspNetCore.Authorization; +using System.Text.Json; [Authorize] [Route("[controller]")] @@ -95,9 +96,9 @@ public class UsersController : Controller return false; } } - + [HttpPost("Update")] - public async Task Update([FromBody]UsersModifyRequestModel requestModel) + public async Task Update([FromBody] UsersModifyRequestModel requestModel) { if (requestModel is null) { @@ -145,4 +146,47 @@ public class UsersController : Controller } return true; } + + [HttpPost("AddGroup")] + public async Task AddGroup([FromBody]UsersAddGroupRequestModel requestModel) + { + try + { + UserModel userModel = await _ldap.GetUserByUidAsync(requestModel.Uid); + userModel.Description ??= new() { Address = new(), BirthDate = "", Workplace = "" }; + userModel.Description.Groups ??= []; + try + { + GroupModel group = await _ldap.GetGroupByCnAsync(requestModel.GroupUid, _ldap.GroupsAttributes); + } catch (Exception) + { + return false; + } + userModel.Description.Groups.Add(requestModel.GroupUid); + await _ldap.UpdateUser(requestModel.Uid, "description", JsonSerializer.Serialize(userModel.Description)); + return true; + } catch (Exception ex) + { + _logger.LogError("Unable to add group {} to user {}: {ex.Message} - {ex.StackTrace}", [requestModel.GroupUid, requestModel.Uid, ex.Message, ex.StackTrace]); + return false; + } + } + + [HttpPost("RemoveGroup")] + public async Task RemoveGroup([FromBody]UsersRemoveGroupRequestModel requestModel) + { + try + { + UserModel userModel = await _ldap.GetUserByUidAsync(requestModel.Uid); + userModel.Description ??= new() { Address = new(), BirthDate = "", Workplace = "" }; + userModel.Description.Groups ??= []; + userModel.Description.Groups.Remove(requestModel.GroupUid); + await _ldap.UpdateUser(requestModel.Uid, "description", JsonSerializer.Serialize(userModel.Description)); + return true; + } catch (Exception ex) + { + _logger.LogError("Unable to remove group {} from user {}: {ex.Message} - {ex.StackTrace}", [requestModel.GroupUid, requestModel.Uid, ex.Message, ex.StackTrace]); + return false; + } + } } diff --git a/src/Models/UserModels.cs b/src/Models/UserModels.cs index 4895d4b..7fe6616 100644 --- a/src/Models/UserModels.cs +++ b/src/Models/UserModels.cs @@ -29,6 +29,7 @@ public class UserDescription public required string BirthDate { get; set; } public required UserAddress Address { get; set; } public required string Workplace { get; set; } + public List? Groups { get; set; } } public class UserAddress @@ -40,8 +41,9 @@ public class UserAddress public class UserAuthenticationResult { - public required bool Success; + public required bool Success { get; set; } public UserNotAuthenticatedReason AuthenticationState { get; set; } = UserNotAuthenticatedReason.None; + public UserModel? UserModel { get; set; } } public enum UserNotAuthenticatedReason diff --git a/src/Models/UsersRequestModels.cs b/src/Models/UsersRequestModels.cs index 7c2436d..0abfe5a 100644 --- a/src/Models/UsersRequestModels.cs +++ b/src/Models/UsersRequestModels.cs @@ -28,4 +28,16 @@ public class UsersDeleteRequestModel(bool successful, string exception = "None") public bool Success { get; set; } = successful; public string? Exception { get; set; } = exception; +} + +public class UsersAddGroupRequestModel +{ + public required string Uid { get; set; } + public required string GroupUid { get; set; } +} + +public class UsersRemoveGroupRequestModel +{ + public required string Uid { get; set; } + public required string GroupUid { get; set; } } \ No newline at end of file diff --git a/src/Services/LdapService.cs b/src/Services/LdapService.cs index 28b1311..a46fe6d 100644 --- a/src/Services/LdapService.cs +++ b/src/Services/LdapService.cs @@ -297,7 +297,7 @@ public async Task CreateAsset(LdapAttributeSet attributeSet) } if (CompareStringToSha256(password, user.UserPassword)) { - return new() { Success = true }; + return new() { Success = true, UserModel = user }; } return new() { Success = false, AuthenticationState = UserNotAuthenticatedReason.InvalidCredentials }; } From 6f6ce058e246c04ebdecdbffdc82412779235328 Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Fri, 17 Oct 2025 18:32:22 +0200 Subject: [PATCH 2/4] Implemented navbar showing elements based on permissions --- src/Views/Shared/_Layout.cshtml | 48 ++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/Views/Shared/_Layout.cshtml b/src/Views/Shared/_Layout.cshtml index 20fc558..1f98dc8 100644 --- a/src/Views/Shared/_Layout.cshtml +++ b/src/Views/Shared/_Layout.cshtml @@ -1,4 +1,5 @@ @using Microsoft.AspNetCore.Mvc.Localization +@using System.Security.Claims @inject IViewLocalizer T @@ -32,23 +33,38 @@ - @if (User.Identity.IsAuthenticated) + @if (User.Identity?.IsAuthenticated ?? false) { - - - - - + @if (User.HasClaim(ClaimTypes.Role, "CanInventorize")) + { + + } + @if (User.HasClaim(ClaimTypes.Role, "CanManageAssets")) + { + + } + @if (User.HasClaim(ClaimTypes.Role, "CanManageLocations")) + { + + } + @if (User.HasClaim(ClaimTypes.Role, "CanManageUsers")) + { + + } + @if (User.HasClaim(ClaimTypes.Role, "CanManageGroups")) + { + + } }