317 lines
12 KiB
C#

using System.Data;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Roles;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Roles;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Model.ViewModels.Roles;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
#nullable disable
namespace MarcoBMS.Services.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class RolesController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly RolesHelper _rolesHelper;
private readonly UserHelper _userHelper;
private readonly UserManager<ApplicationUser> _userManager;
public RolesController(UserManager<ApplicationUser> userManager, ApplicationDbContext context, RolesHelper rolesHelper, UserHelper userHelper)
{
_context = context;
_userManager = userManager;
_rolesHelper = rolesHelper;
_userHelper = userHelper;
}
private Guid GetTenantId()
{
return _userHelper.GetTenantId();
}
[HttpGet("jobrole")]
public async Task<IActionResult> GetAllJobRoles()
{
Guid TenantId = GetTenantId();
var roles = await _context.JobRoles.Where(c => c.TenantId == TenantId).Select(x => new JobRoleVM()
{
Id = x.Id,
Name = x.Name,
Description = x.Description
}).ToListAsync();
return Ok(ApiResponse<object>.SuccessResponse(roles, "Success.", 200));
}
[HttpPost("jobrole")]
public async Task<IActionResult> AddJobRole([FromBody] CreateJobRoleDto createJobRoleDto)
{
Guid TenantId = GetTenantId();
if (await _context.JobRoles.AnyAsync(c => c.Name.ToLower() == createJobRoleDto.Name.ToLower() && c.TenantId == TenantId))
{
return BadRequest(ApiResponse<object>.ErrorResponse("Role with same name already Exists.", "Role with same name already Exists.", 400));
}
else
{
JobRole jr = createJobRoleDto.ToJobRoleFromCreateJobRoleDot(TenantId);
_context.JobRoles.Add(jr);
await _context.SaveChangesAsync();
return Ok(ApiResponse<object>.SuccessResponse(jr, "Success.", 200));
}
}
[HttpPut("jobrole/{id}")]
public async Task<IActionResult> UpdateJobRole(string id, [FromBody] UpdateJobRoleDto updateRoleDto)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
if (id != updateRoleDto.Id.ToString())
return BadRequest(ApiResponse<object>.ErrorResponse("Role ID mismatch", "Role ID mismatch", 400));
try
{
Guid TenantId = GetTenantId();
JobRole jr = updateRoleDto.ToJobRoleFromUpdateJobRoleDot(TenantId);
_context.JobRoles.Update(jr);
await _context.SaveChangesAsync();
return Ok(ApiResponse<object>.SuccessResponse(jr, "Success.", 200));
}
catch (Exception ex)
{
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
}
}
[HttpGet]
public async Task<IActionResult> GetAllRoles()
{
Guid TenantId = GetTenantId();
var roles = await _context.ApplicationRoles.Where(c => c.TenantId == TenantId).ToListAsync();
var roleFeaturePermissions = await _context.RolePermissionMappings
.Join(
_context.FeaturePermissions,
rfp => rfp.FeaturePermissionId,
fp => fp.Id,
(rfp, fp) => new { rfp.ApplicationRoleId, FeaturePermission = fp })
.Join(
_context.ApplicationRoles,
result => result.ApplicationRoleId,
role => role.Id,
(result, role) => new { Role = role, result.FeaturePermission })
.Where(x => x.Role.TenantId == TenantId) // Filter by TenantId
.Select(x => new
{
RoleId = x.Role.Id,
RoleName = x.Role.Role,
FeaturePermission = x.FeaturePermission
})
.ToListAsync();
List<ApplicationRolesVM> applicationRoles = new List<ApplicationRolesVM>();
foreach (var item in roles)
{
var rolesVM = new ApplicationRolesVM()
{
Id = item.Id,
Role = item.Role,
Description = item.Description,
FeaturePermission = []
};
ICollection<FeaturePermission> permissions = roleFeaturePermissions.Where(c => c.RoleId == item.Id)
.Select(c => c.FeaturePermission).ToList();
foreach (var permission in permissions)
{
rolesVM.FeaturePermission.Add(
new FeaturePermissionVM()
{
Id = permission.Id,
Description = permission.Description,
FeatureId = permission.FeatureId,
IsEnabled = permission.IsEnabled,
Name = permission.Name
});
}
applicationRoles.Add(rolesVM);
}
return Ok(ApiResponse<object>.SuccessResponse(applicationRoles, "Roles list fetched successfully.", 200));
}
[HttpPost]
public async Task<IActionResult> AddRole([FromBody] CreateApplicationRoleDto createRoleDto)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
Guid TenantId = GetTenantId();
if (createRoleDto.FeaturesPermission == null || (createRoleDto.FeaturesPermission != null && createRoleDto.FeaturesPermission.Count == 0))
{
return BadRequest(ApiResponse<object>.ErrorResponse("Feature Permission is required.", "Feature Permission is required.", 400));
}
bool roleExists = _context.ApplicationRoles
.Any(r => r.TenantId == TenantId && r.Role.ToLower() == createRoleDto.Role.ToLower());// assuming role name is unique per tenant
if (roleExists)
{
return BadRequest(ApiResponse<object>.ErrorResponse("Role already exists.", "Role already exists.", 400));
}
ApplicationRole role = createRoleDto.ToApplicationRoleFromCreateDto(TenantId);
_context.ApplicationRoles.Add(role);
foreach (var permission in createRoleDto.FeaturesPermission)
{
var item = new RolePermissionMappings() { ApplicationRoleId = role.Id, FeaturePermissionId = permission.Id };
bool assigned = _context.RolePermissionMappings.Any(c => c.ApplicationRoleId == role.Id && c.FeaturePermissionId == permission.Id);
if (permission.IsEnabled && !assigned)
_context.RolePermissionMappings.Add(item);
else
_context.RolePermissionMappings.Remove(item);
}
await _context.SaveChangesAsync();
return Ok(ApiResponse<object>.SuccessResponse(role.ToRoleVMFromApplicationRole(), "Roles created successfully.", 200));
}
[HttpPut("{id}")]
public async Task<IActionResult> UpdateRole(Guid id, [FromBody] UpdateApplicationRoleDto updateRoleDto)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
if (id != updateRoleDto.Id)
return BadRequest("Role ID mismatch");
try
{
Guid TenantId = GetTenantId();
ApplicationRole role = updateRoleDto.ToApplicationRoleFromUpdateDto(TenantId);
if (role.TenantId != TenantId)
return Unauthorized(ApiResponse<object>.ErrorResponse("You don't have any authority to update role", "You don't have any authority to update role", 401));
var projectModel = _context.ApplicationRoles.Update(role);
if (projectModel == null)
{
return NotFound(ApiResponse<object>.ErrorResponse("Project not found", "Project not found", 404));
}
bool modified = false;
foreach (var permission in updateRoleDto.FeaturesPermission)
{
var item = new RolePermissionMappings() { ApplicationRoleId = role.Id, FeaturePermissionId = permission.Id };
bool assigned = _context.RolePermissionMappings.Any(c => c.ApplicationRoleId == role.Id && c.FeaturePermissionId == permission.Id);
if (permission.IsEnabled == false && assigned == true)
{
_context.RolePermissionMappings.Remove(item);
modified = true;
}
else if (permission.IsEnabled && !assigned)
{
_context.RolePermissionMappings.Add(item);
modified = true;
}
}
if (modified)
await _context.SaveChangesAsync();
ApplicationRolesVM response = role.ToRoleVMFromApplicationRole();
List<FeaturePermission> permissions = await _rolesHelper.GetFeaturePermissionByRoleID(response.Id);
response.FeaturePermission = permissions.Select(c => c.ToFeaturePermissionVMFromFeaturePermission()).ToList();
return Ok(ApiResponse<object>.SuccessResponse(response, "Roles perimssions updated.", 200));
}
catch (Exception ex)
{
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
}
}
[HttpGet("{id}")]
public async Task<IActionResult> GetRoleById(Guid id)
{
Guid TenantId = GetTenantId();
var role = await _context.ApplicationRoles.FindAsync(id);
if (role == null)
return NotFound(ApiResponse<object>.ErrorResponse("Role not found", "Role not found", 404));
if (role.TenantId != TenantId)
return Unauthorized(ApiResponse<object>.ErrorResponse("You don't have any authority", "You don't have any authority", 401));
var featurePermissions = await _context.RolePermissionMappings
.Where(rfp => rfp.ApplicationRoleId == id)
.Join(
_context.FeaturePermissions,
rfp => rfp.FeaturePermissionId,
fp => fp.Id,
(rfp, fp) => new FeaturePermissionVM()
{
Id = fp.Id,
Name = fp.Name,
Description = fp.Description,
IsEnabled = fp.IsEnabled,
FeatureId = fp.FeatureId
})
.ToListAsync();
ApplicationRolesVM vm = new ApplicationRolesVM()
{
Id = role.Id,
Role = role.Role,
FeaturePermission = featurePermissions
};
return Ok(ApiResponse<object>.SuccessResponse(vm, "Roles Perimssions fetched successfully.", 200));
}
}
}