using System.Threading;
using System.Threading.Tasks;
using GB5Shared.DTO.Framework.Login;
using GB5Shared.Telemetry;
using Microsoft.Extensions.Logging;
namespace GB5Shared.Authorization
{
///
/// GB5-native port of the legacy ServiceAutorizationCheckBLL.CheckServiceRightsNew role-vs-menu
/// check (Downloads/framework/AuthorizationChecking/Authorization/ServiceAutorizationCheckBLL.cs).
/// The legacy engine additionally overlaid MADVANCERIGHTS (per-user, BizTransaction-scoped finer
/// rights) on top of this role-level check — that overlay is intentionally not ported yet, since
/// it requires the BizTransactionClass/Type/Transaction resolution chain and there is no live DB
/// available this session to verify its current GB5 schema shape against. This class is the
/// role-level gate only; the advance-rights overlay is a documented follow-up extension point.
///
public class MenuRightsBLL : IMenuRightsBLL
{
private readonly IMenuRightsDAL _dal;
private readonly ILogger _logger;
public MenuRightsBLL(IMenuRightsDAL dal, ILogger logger)
{
_dal = dal;
_logger = logger;
}
public async Task IsAllowedAsync(string menuCode, RightOperation operation, LoginDTO login, CancellationToken ct)
{
GB5Trace.Step("menu-rights-check", new { menuCode, operation, login.RoleId });
string? allow = await _dal.GetAllowStringAsync(menuCode, login.RoleId, login, ct).ConfigureAwait(false);
if (string.IsNullOrEmpty(allow))
{
_logger.LogWarning(
"MenuRights denied: no MROLEVSMENU grant for RoleId {RoleId}, MenuCode {MenuCode}",
login.RoleId, menuCode);
return false;
}
int position = (int)operation;
if (position >= allow.Length)
{
_logger.LogWarning(
"MenuRights denied: ALLOW string '{Allow}' for MenuCode {MenuCode} has no position {Position}",
allow, menuCode, position);
return false;
}
bool allowed = allow[position] == '0';
if (!allowed)
{
_logger.LogWarning(
"MenuRights denied: RoleId {RoleId} lacks {Operation} on MenuCode {MenuCode} (Allow={Allow})",
login.RoleId, operation, menuCode, allow);
GB5Trace.MarkFailed("menu-rights-denied");
}
return allowed;
}
}
}