mirror of
https://github.com/LD-Reborn/Berufsschule_HAM.git
synced 2025-12-20 06:51:55 +00:00
Merge pull request #142 from LD-Reborn/141-feature-implement-proper-authorization-with-groups
141 feature implement proper authorization with groups
This commit is contained in:
@@ -20,6 +20,7 @@ public class AssetsController : Controller
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "CanManageAssets,CanInventorize")]
|
||||||
[HttpGet("Get")]
|
[HttpGet("Get")]
|
||||||
public async Task<AssetsGetResponseModel> GetAllAssetModelAsync(string Cn)
|
public async Task<AssetsGetResponseModel> GetAllAssetModelAsync(string Cn)
|
||||||
{
|
{
|
||||||
@@ -41,6 +42,7 @@ public class AssetsController : Controller
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "CanManageAssets")]
|
||||||
[HttpGet("GetAll")]
|
[HttpGet("GetAll")]
|
||||||
public async Task<AssetsGetAllResponseModel> GetAllAssetModelAsync()
|
public async Task<AssetsGetAllResponseModel> GetAllAssetModelAsync()
|
||||||
{
|
{
|
||||||
@@ -63,6 +65,7 @@ public class AssetsController : Controller
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "CanManageAssets")]
|
||||||
[HttpPost("Create")]
|
[HttpPost("Create")]
|
||||||
public async Task<AssetsCreateResponseModel> Create([FromBody]AssetsCreateRequestModel assetModel)
|
public async Task<AssetsCreateResponseModel> Create([FromBody]AssetsCreateRequestModel assetModel)
|
||||||
{
|
{
|
||||||
@@ -117,6 +120,7 @@ public class AssetsController : Controller
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "CanManageAssets")]
|
||||||
[HttpDelete("Delete")]
|
[HttpDelete("Delete")]
|
||||||
public async Task<AssetsDeleteResponseModel> Delete([BindRequired] string cn)
|
public async Task<AssetsDeleteResponseModel> Delete([BindRequired] string cn)
|
||||||
{
|
{
|
||||||
@@ -143,6 +147,7 @@ public class AssetsController : Controller
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "CanManageAssets,CanInventorize")]
|
||||||
[HttpPatch("Update")]
|
[HttpPatch("Update")]
|
||||||
public async Task<AssetsUpdateResponseModel> Update([FromBody] AssetsModifyRequestModel requestModel)
|
public async Task<AssetsUpdateResponseModel> Update([FromBody] AssetsModifyRequestModel requestModel)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Berufsschule_HAM.Models;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageGroups")]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class GroupsController : Controller
|
public class GroupsController : Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class HomeController : Controller
|
|||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageAssets")]
|
||||||
[HttpGet("Assets")]
|
[HttpGet("Assets")]
|
||||||
public async Task<IActionResult> Assets()
|
public async Task<IActionResult> Assets()
|
||||||
{
|
{
|
||||||
@@ -48,14 +48,14 @@ public class HomeController : Controller
|
|||||||
return View(new HomeIndexViewModel() { AssetsTableViewModels = assetsTableViewModels });
|
return View(new HomeIndexViewModel() { AssetsTableViewModels = assetsTableViewModels });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanInventorize")]
|
||||||
[HttpGet("Inventory")]
|
[HttpGet("Inventory")]
|
||||||
public ActionResult Inventory()
|
public ActionResult Inventory()
|
||||||
{
|
{
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageLocations")]
|
||||||
[HttpGet("Locations")]
|
[HttpGet("Locations")]
|
||||||
public async Task<ActionResult> LocationsAsync()
|
public async Task<ActionResult> LocationsAsync()
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@ public class HomeController : Controller
|
|||||||
return View(new LocationsIndexViewModel() { LocationTableViewModels = LocationsTableViewModels });
|
return View(new LocationsIndexViewModel() { LocationTableViewModels = LocationsTableViewModels });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageUsers")]
|
||||||
[HttpGet("Users")]
|
[HttpGet("Users")]
|
||||||
public async Task<ActionResult> UsersAsync()
|
public async Task<ActionResult> UsersAsync()
|
||||||
{
|
{
|
||||||
@@ -95,7 +95,7 @@ public class HomeController : Controller
|
|||||||
return View(new UsersIndexViewModel() { UserTableViewModels = UserTableViewModels });
|
return View(new UsersIndexViewModel() { UserTableViewModels = UserTableViewModels });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageGroups")]
|
||||||
[HttpGet("Groups")]
|
[HttpGet("Groups")]
|
||||||
public async Task<ActionResult> GroupsAsync()
|
public async Task<ActionResult> GroupsAsync()
|
||||||
{
|
{
|
||||||
@@ -113,6 +113,19 @@ public class HomeController : Controller
|
|||||||
[
|
[
|
||||||
new(ClaimTypes.Name, username)
|
new(ClaimTypes.Name, username)
|
||||||
];
|
];
|
||||||
|
HashSet<string> 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(
|
var claimsIdentity = new ClaimsIdentity(
|
||||||
claims,
|
claims,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Novell.Directory.Ldap;
|
using Novell.Directory.Ldap;
|
||||||
using Berufsschule_HAM.Helpers;
|
using Berufsschule_HAM.Helpers;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageLocations")]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class LocationsController : Controller
|
public class LocationsController : Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ using Berufsschule_HAM.Helpers;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize(Roles = "CanManageUsers")]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class UsersController : Controller
|
public class UsersController : Controller
|
||||||
{
|
{
|
||||||
@@ -95,9 +96,9 @@ public class UsersController : Controller
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Update")]
|
[HttpPost("Update")]
|
||||||
public async Task<bool> Update([FromBody]UsersModifyRequestModel requestModel)
|
public async Task<bool> Update([FromBody] UsersModifyRequestModel requestModel)
|
||||||
{
|
{
|
||||||
if (requestModel is null)
|
if (requestModel is null)
|
||||||
{
|
{
|
||||||
@@ -145,4 +146,47 @@ public class UsersController : Controller
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("AddGroup")]
|
||||||
|
public async Task<bool> 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<bool> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public class UserDescription
|
|||||||
public required string BirthDate { get; set; }
|
public required string BirthDate { get; set; }
|
||||||
public required UserAddress Address { get; set; }
|
public required UserAddress Address { get; set; }
|
||||||
public required string Workplace { get; set; }
|
public required string Workplace { get; set; }
|
||||||
|
public List<string>? Groups { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserAddress
|
public class UserAddress
|
||||||
@@ -40,8 +41,9 @@ public class UserAddress
|
|||||||
|
|
||||||
public class UserAuthenticationResult
|
public class UserAuthenticationResult
|
||||||
{
|
{
|
||||||
public required bool Success;
|
public required bool Success { get; set; }
|
||||||
public UserNotAuthenticatedReason AuthenticationState { get; set; } = UserNotAuthenticatedReason.None;
|
public UserNotAuthenticatedReason AuthenticationState { get; set; } = UserNotAuthenticatedReason.None;
|
||||||
|
public UserModel? UserModel { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UserNotAuthenticatedReason
|
public enum UserNotAuthenticatedReason
|
||||||
|
|||||||
@@ -28,4 +28,16 @@ public class UsersDeleteRequestModel(bool successful, string exception = "None")
|
|||||||
public bool Success { get; set; } = successful;
|
public bool Success { get; set; } = successful;
|
||||||
|
|
||||||
public string? Exception { get; set; } = exception;
|
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; }
|
||||||
}
|
}
|
||||||
@@ -297,7 +297,7 @@ public async Task CreateAsset(LdapAttributeSet attributeSet)
|
|||||||
}
|
}
|
||||||
if (CompareStringToSha256(password, user.UserPassword))
|
if (CompareStringToSha256(password, user.UserPassword))
|
||||||
{
|
{
|
||||||
return new() { Success = true };
|
return new() { Success = true, UserModel = user };
|
||||||
}
|
}
|
||||||
return new() { Success = false, AuthenticationState = UserNotAuthenticatedReason.InvalidCredentials };
|
return new() { Success = false, AuthenticationState = UserNotAuthenticatedReason.InvalidCredentials };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@using Microsoft.AspNetCore.Mvc.Localization
|
@using Microsoft.AspNetCore.Mvc.Localization
|
||||||
|
@using System.Security.Claims
|
||||||
@inject IViewLocalizer T
|
@inject IViewLocalizer T
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -32,23 +33,38 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Index">@T["Quick-Actions"]</a>
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Index">@T["Quick-Actions"]</a>
|
||||||
</li>
|
</li>
|
||||||
@if (User.Identity.IsAuthenticated)
|
@if (User.Identity?.IsAuthenticated ?? false)
|
||||||
{
|
{
|
||||||
<li class="nav-item">
|
@if (User.HasClaim(ClaimTypes.Role, "CanInventorize"))
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Inventory">@T["Inventory"]</a>
|
{
|
||||||
</li>
|
<li class="nav-item">
|
||||||
<li class="nav-item">
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Inventory">@T["Inventory"]</a>
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Assets">@T["Assets"]</a>
|
</li>
|
||||||
</li>
|
}
|
||||||
<li class="nav-item">
|
@if (User.HasClaim(ClaimTypes.Role, "CanManageAssets"))
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Locations">@T["Locations"]</a>
|
{
|
||||||
</li>
|
<li class="nav-item">
|
||||||
<li class="nav-item">
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Assets">@T["Assets"]</a>
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Users">@T["Users"]</a>
|
</li>
|
||||||
</li>
|
}
|
||||||
<li class="nav-item">
|
@if (User.HasClaim(ClaimTypes.Role, "CanManageLocations"))
|
||||||
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Groups">@T["Groups"]</a>
|
{
|
||||||
</li>
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Locations">@T["Locations"]</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
@if (User.HasClaim(ClaimTypes.Role, "CanManageUsers"))
|
||||||
|
{
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Users">@T["Users"]</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
@if (User.HasClaim(ClaimTypes.Role, "CanManageGroups"))
|
||||||
|
{
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text" asp-area="" asp-controller="Home" asp-action="Groups">@T["Groups"]</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@if (User.Identity.IsAuthenticated)
|
@if (User.Identity.IsAuthenticated)
|
||||||
|
|||||||
Reference in New Issue
Block a user