Compare commits
27 Commits
1b21ccecf3
...
65ad9e6da0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65ad9e6da0 | ||
|
|
0ef327a059 | ||
|
|
2a9e0a8f17 | ||
|
|
d6aac0b400 | ||
|
|
6d25f8d3bd | ||
|
|
eb45c6aefa | ||
|
|
79167a7f9d | ||
|
|
2a81f33340 | ||
|
|
4e5a68fa89 | ||
|
|
2d2f35c972 | ||
|
|
c606fe4480 | ||
|
|
fa26fad600 | ||
|
|
6da7f33437 | ||
|
|
6fcddfc7b9 | ||
|
|
ae59ffe73b | ||
|
|
94a2d414d3 | ||
|
|
c7f1be7c58 | ||
|
|
70d7ed7415 | ||
|
|
0351f8733d | ||
|
|
26b57e5475 | ||
|
|
2c66112d4d | ||
|
|
5327249f5e | ||
|
|
f300b640a2 | ||
|
|
6a062045bb | ||
|
|
22f69589c9 | ||
|
|
ca94368d0b | ||
|
|
05701c10d2 |
145
WorkFlow.API/Controllers/AuthController.cs
Normal file
145
WorkFlow.API/Controllers/AuthController.cs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using DigitalData.UserManager.Application.Contracts;
|
||||||
|
using DigitalData.UserManager.Application.DTOs.User;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using DigitalData.UserManager.Application;
|
||||||
|
using DigitalData.UserManager.Application.DTOs.Auth;
|
||||||
|
using DigitalData.Core.Abstractions.Application;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class AuthController(IUserService userService, IGroupOfUserService gouService, IDirectorySearchService directorySearchService, IStringLocalizer<Resource> localizer, ILogger<AuthController> logger) : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IUserService _userService = userService;
|
||||||
|
private readonly IGroupOfUserService _gouService = gouService;
|
||||||
|
private readonly IDirectorySearchService _dirSearchService = directorySearchService;
|
||||||
|
private readonly IStringLocalizer<Resource> _localizer = localizer;
|
||||||
|
private readonly ILogger<AuthController> _logger = logger;
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("check")]
|
||||||
|
public IActionResult CheckAuthentication()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Ok(User.Identity?.IsAuthenticated ?? false);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("login")]
|
||||||
|
public async Task<IActionResult> Login([FromBody] LogInDto login)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isValid = _dirSearchService.ValidateCredentials(login.Username, login.Password);
|
||||||
|
|
||||||
|
if (!isValid)
|
||||||
|
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
|
||||||
|
|
||||||
|
var gouMsg = await _gouService.HasGroup(login.Username, "PM_USER", caseSensitive: false);
|
||||||
|
if (!gouMsg.IsSuccess)
|
||||||
|
return Unauthorized(Result.Fail().Message(_localizer[Key.UnauthorizedUser]));
|
||||||
|
|
||||||
|
//find the user
|
||||||
|
var uRes = await _userService.ReadByUsernameAsync(login.Username);
|
||||||
|
if (!uRes.IsSuccess || uRes.Data is null)
|
||||||
|
{
|
||||||
|
return Unauthorized(uRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserReadDto user = uRes.Data;
|
||||||
|
|
||||||
|
// Create claims
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new (ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
|
new (ClaimTypes.Name, user.Username),
|
||||||
|
new (ClaimTypes.Surname, user.Name ?? ""),
|
||||||
|
new (ClaimTypes.GivenName, user.Prename ?? ""),
|
||||||
|
new (ClaimTypes.Email, user.Email ?? "")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create claimsIdentity
|
||||||
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
|
||||||
|
// Create authProperties
|
||||||
|
var authProperties = new AuthenticationProperties
|
||||||
|
{
|
||||||
|
IsPersistent = true,
|
||||||
|
AllowRefresh = true,
|
||||||
|
ExpiresUtc = DateTime.UtcNow.AddMinutes(60)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sign in
|
||||||
|
await HttpContext.SignInAsync(
|
||||||
|
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||||
|
new ClaimsPrincipal(claimsIdentity),
|
||||||
|
authProperties);
|
||||||
|
|
||||||
|
_dirSearchService.SetSearchRootCache(user.Username, login.Password);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("user")]
|
||||||
|
public async Task<IActionResult> GetUserWithClaims()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Extract the username from the Name claim.
|
||||||
|
string? username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(username))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return await _userService.ReadByUsernameAsync(username)
|
||||||
|
.ThenAsync(Ok, IActionResult (m, n) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(n);
|
||||||
|
return NotFound(Result.Fail().Message(_localizer[Key.UserNotFound]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[HttpPost("logout")]
|
||||||
|
public async Task<IActionResult> Logout()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
WorkFlow.API/Controllers/ConfigController.cs
Normal file
16
WorkFlow.API/Controllers/ConfigController.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using DigitalData.Core.API;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WorkFlow.Application.Contracts;
|
||||||
|
using WorkFlow.Application.DTO.Config;
|
||||||
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ConfigController(ILogger<ConfigController> logger, IConfigService service) : CRUDControllerBaseWithErrorHandling<IConfigService, ConfigCreateDto, ConfigDto, ConfigUpdateDto, Config, int>(logger, service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
94
WorkFlow.API/Controllers/ControllerExtensions.cs
Normal file
94
WorkFlow.API/Controllers/ControllerExtensions.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
public static class ControllerExtensions
|
||||||
|
{
|
||||||
|
public static bool TryGetUserId(this ControllerBase controller, out int? id)
|
||||||
|
{
|
||||||
|
var value = controller.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
id = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(int.TryParse(value, out int id_int))
|
||||||
|
{
|
||||||
|
id = id_int;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetUsername(this ControllerBase controller, out string username)
|
||||||
|
{
|
||||||
|
var value = controller.User.FindFirstValue(ClaimTypes.Name);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
username = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
username = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetName(this ControllerBase controller, out string name)
|
||||||
|
{
|
||||||
|
var value = controller.User.FindFirstValue(ClaimTypes.Surname);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
name = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetPrename(this ControllerBase controller, out string prename)
|
||||||
|
{
|
||||||
|
var value = controller.User.FindFirstValue(ClaimTypes.GivenName);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
prename = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prename = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetEmail(this ControllerBase controller, out string email)
|
||||||
|
{
|
||||||
|
var value = controller.User.FindFirstValue(ClaimTypes.Email);
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
email = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
email = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
WorkFlow.API/Controllers/ProfileController.cs
Normal file
16
WorkFlow.API/Controllers/ProfileController.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using DigitalData.Core.API;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WorkFlow.Application.Contracts;
|
||||||
|
using WorkFlow.Application.DTO.Profile;
|
||||||
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ProfileController(ILogger<ProfileController> logger, IProfileService service) : CRUDControllerBaseWithErrorHandling<IProfileService, ProfileCreateDto, ProfileDto, ProfileUpdateDto, Profile, int>(logger, service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
118
WorkFlow.API/Controllers/ProfileControlsTFController.cs
Normal file
118
WorkFlow.API/Controllers/ProfileControlsTFController.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using DigitalData.Core.API;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WorkFlow.Application.Contracts;
|
||||||
|
using WorkFlow.Application.DTO.ProfileControlsTF;
|
||||||
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ProfileControlsTFController(ILogger<ProfileControlsTFController> logger, IProfileControlsTFService service) : CRUDControllerBase<IProfileControlsTFService, ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>(logger, service)
|
||||||
|
{
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> GetAll() => base.GetAll();
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> Update(ProfileControlsTFUpdateDto updateDto) => base.Update(updateDto);
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAsync(
|
||||||
|
bool withProfile = true, bool withUser = false,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? id))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (id is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _service.ReadAsync(
|
||||||
|
withProfile: withProfile, withUser: withUser,
|
||||||
|
userId: id,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive)
|
||||||
|
.ThenAsync(
|
||||||
|
Success: pctf => pctf.Any() ? Ok(pctf) : NotFound(),
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
logger.LogNotice(ntc);
|
||||||
|
return NotFound();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public override async Task<IActionResult> Create([FromBody] ProfileControlsTFCreateDto createDto)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? id))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (id is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createDto.UserId != id)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return await base.Create(createDto);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
public override async Task<IActionResult> Delete([FromRoute] int id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? userId))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (userId is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _service.ReadByIdAsync(id).ThenAsync(
|
||||||
|
SuccessAsync: async pctf => pctf.UserId == userId ? await base.Delete(id) : Unauthorized(),
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
118
WorkFlow.API/Controllers/ProfileObjStateController.cs
Normal file
118
WorkFlow.API/Controllers/ProfileObjStateController.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using DigitalData.Core.API;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WorkFlow.Application.Contracts;
|
||||||
|
using WorkFlow.Application.DTO.ProfileObjState;
|
||||||
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ProfileObjStateController(ILogger<ProfileObjStateController> logger, IProfileObjStateService service) : CRUDControllerBaseWithErrorHandling<IProfileObjStateService, ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>(logger, service)
|
||||||
|
{
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> GetAll() => base.GetAll();
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> Update(ProfileObjStateUpdateDto updateDto) => base.Update(updateDto);
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAsync(
|
||||||
|
bool withProfile = true, bool withUser = true, bool withState = true,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? id))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (id is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _service.ReadAsync(
|
||||||
|
withProfile: withProfile, withUser: withUser, withState,
|
||||||
|
userId: id,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive)
|
||||||
|
.ThenAsync(
|
||||||
|
Success: pctf => pctf.Any() ? Ok(pctf) : NotFound(),
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
logger.LogNotice(ntc);
|
||||||
|
return NotFound();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public override async Task<IActionResult> Create([FromBody] ProfileObjStateCreateDto createDto)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? id))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (id is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createDto.UserId != id)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return await base.Create(createDto);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
public override async Task<IActionResult> Delete([FromRoute] int id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? userId))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if (userId is null)
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _service.ReadByIdAsync(id).ThenAsync(
|
||||||
|
SuccessAsync: async pctf => pctf.UserId == userId ? await base.Delete(id) : Unauthorized(),
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
WorkFlow.API/Controllers/StateController.cs
Normal file
16
WorkFlow.API/Controllers/StateController.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using DigitalData.Core.API;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WorkFlow.Application.Contracts;
|
||||||
|
using WorkFlow.Application.DTO.State;
|
||||||
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class StateController(ILogger<StateController> logger, IStateService service) : CRUDControllerBaseWithErrorHandling<IStateService, StateCreateDto, StateDto, StateUpdateDto, State, int>(logger, service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
44
WorkFlow.API/Controllers/UserController.cs
Normal file
44
WorkFlow.API/Controllers/UserController.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using DigitalData.Core.DTO;
|
||||||
|
using DigitalData.UserManager.Application.Contracts;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace WorkFlow.API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class UserController(ILogger<UserController> logger, IUserService userService) : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.TryGetUserId(out int? id))
|
||||||
|
{
|
||||||
|
logger.LogError("Authorization failed: User ID claim not found.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Failed to retrieve user identity.");
|
||||||
|
}
|
||||||
|
else if(id is int id_int)
|
||||||
|
return await userService.ReadByIdAsync(id_int).ThenAsync(
|
||||||
|
Success: Ok,
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
logger.LogNotice(ntc);
|
||||||
|
return NotFound();
|
||||||
|
});
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogError("Invalid user ID: Retrieved ID is null or not an integer.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Invalid user ID.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "An unexpected error occurred while processing the request: {Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "An internal server error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
WorkFlow.API/Program.cs
Normal file
47
WorkFlow.API/Program.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using WorkFlow.Application;
|
||||||
|
using DigitalData.UserManager.Application;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using WorkFlow.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
var config = builder.Configuration;
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
var cnn_str = config.GetConnectionString("Default") ?? throw new ("Default connection string not found.");
|
||||||
|
builder.Services.AddDbContext<WFDBContext>(options => options.UseSqlServer(cnn_str).EnableDetailedErrors());
|
||||||
|
builder.Services.AddWorkFlow().AddUserManager<WFDBContext>();
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
|
.AddCookie(options =>
|
||||||
|
{
|
||||||
|
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
|
||||||
|
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
|
||||||
|
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
|
||||||
|
options.LoginPath = "/api/auth/login";
|
||||||
|
options.LogoutPath = "/api/auth/logout";
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
41
WorkFlow.API/Properties/launchSettings.json
Normal file
41
WorkFlow.API/Properties/launchSettings.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:56180",
|
||||||
|
"sslPort": 44397
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5130",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7120;http://localhost:5130",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
WorkFlow.API/WorkFlow.API.csproj
Normal file
18
WorkFlow.API/WorkFlow.API.csproj
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DigitalData.Core.API" Version="2.0.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\WorkFlow.Application\WorkFlow.Application.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
8
WorkFlow.API/appsettings.Development.json
Normal file
8
WorkFlow.API/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
WorkFlow.API/appsettings.json
Normal file
12
WorkFlow.API/appsettings.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=g+2edXEbMbujCUjh7INZRQ==;Password=Bz/n9pu8EyzlVqicaMRQGQ==;Encrypt=false;TrustServerCertificate=True;"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using DigitalData.Core.Abstractions.Application;
|
using DigitalData.Core.Abstractions.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using WorkFlow.Application.DTO.ProfileControlsTF;
|
using WorkFlow.Application.DTO.ProfileControlsTF;
|
||||||
using WorkFlow.Domain.Entities;
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
@ -6,5 +7,9 @@ namespace WorkFlow.Application.Contracts
|
|||||||
{
|
{
|
||||||
public interface IProfileControlsTFService : ICRUDService<ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>
|
public interface IProfileControlsTFService : ICRUDService<ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>
|
||||||
{
|
{
|
||||||
|
Task<DataResult<IEnumerable<ProfileControlsTFDto>>> ReadAsync(
|
||||||
|
bool withProfile = true, bool withUser = false,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using DigitalData.Core.Abstractions.Application;
|
using DigitalData.Core.Abstractions.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using WorkFlow.Application.DTO.ProfileObjState;
|
using WorkFlow.Application.DTO.ProfileObjState;
|
||||||
using WorkFlow.Domain.Entities;
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
@ -6,5 +7,9 @@ namespace WorkFlow.Application.Contracts
|
|||||||
{
|
{
|
||||||
public interface IProfileObjStateService : ICRUDService<ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>
|
public interface IProfileObjStateService : ICRUDService<ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>
|
||||||
{
|
{
|
||||||
|
Task<DataResult<IEnumerable<ProfileObjStateDto>>> ReadAsync(
|
||||||
|
bool withProfile = true, bool withUser = true, bool withState = true,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
public record ProfileControlsTFCreateDto(int Id,
|
public record ProfileControlsTFCreateDto(int Id,
|
||||||
int ProfileId,
|
int ProfileId,
|
||||||
int UsrId,
|
int UserId,
|
||||||
long ObjId,
|
long ObjId,
|
||||||
string ObjType,
|
string ObjType,
|
||||||
string AttrName,
|
string AttrName,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace WorkFlow.Application.DTO.ProfileControlsTF
|
|||||||
{
|
{
|
||||||
public record ProfileControlsTFDto(int Id,
|
public record ProfileControlsTFDto(int Id,
|
||||||
int ProfileId,
|
int ProfileId,
|
||||||
int UsrId,
|
int UserId,
|
||||||
long ObjId,
|
long ObjId,
|
||||||
string ObjType,
|
string ObjType,
|
||||||
string AttrName,
|
string AttrName,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
public record ProfileObjStateCreateDto(
|
public record ProfileObjStateCreateDto(
|
||||||
int ProfileId,
|
int ProfileId,
|
||||||
int UsrId,
|
int UserId,
|
||||||
long ObjId,
|
long ObjId,
|
||||||
int StateId,
|
int StateId,
|
||||||
string? State2 = null,
|
string? State2 = null,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace WorkFlow.Application.DTO.ProfileObjState
|
|||||||
{
|
{
|
||||||
public record ProfileObjStateDto(int Id,
|
public record ProfileObjStateDto(int Id,
|
||||||
int ProfileId,
|
int ProfileId,
|
||||||
int UsrId,
|
int UserId,
|
||||||
long ObjId,
|
long ObjId,
|
||||||
int StateId,
|
int StateId,
|
||||||
string AddedWho,
|
string AddedWho,
|
||||||
|
|||||||
@ -1,16 +1,32 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using DigitalData.Core.Abstractions.Application;
|
using DigitalData.Core.Abstractions.Application;
|
||||||
using DigitalData.Core.Application;
|
using DigitalData.Core.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using WorkFlow.Application.Contracts;
|
using WorkFlow.Application.Contracts;
|
||||||
using WorkFlow.Application.DTO.ProfileControlsTF;
|
using WorkFlow.Application.DTO.ProfileControlsTF;
|
||||||
using WorkFlow.Domain.Entities;
|
using WorkFlow.Domain.Entities;
|
||||||
using WorkFlow.Infrastructure.Repositories;
|
using WorkFlow.Infrastructure.Contracts;
|
||||||
|
|
||||||
namespace WorkFlow.Application.Services
|
namespace WorkFlow.Application.Services
|
||||||
{
|
{
|
||||||
public class ProfileControlsTFService(ProfileControlsTFRepository repository, IMapper mapper)
|
public class ProfileControlsTFService(IProfileControlsTFRepository repository, IMapper mapper)
|
||||||
: CRUDService<ProfileControlsTFRepository, ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>(repository, mapper),
|
: CRUDService<IProfileControlsTFRepository, ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>(repository, mapper),
|
||||||
IProfileControlsTFService, ICRUDService<ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>
|
IProfileControlsTFService, ICRUDService<ProfileControlsTFCreateDto, ProfileControlsTFDto, ProfileControlsTFUpdateDto, ProfileControlsTF, int>
|
||||||
{
|
{
|
||||||
|
public async Task<DataResult<IEnumerable<ProfileControlsTFDto>>> ReadAsync(
|
||||||
|
bool withProfile = true, bool withUser = false,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
|
{
|
||||||
|
var pctf_list = await _repository.ReadAsync(
|
||||||
|
isReadonly: true,
|
||||||
|
withProfile: withProfile, withUser: withUser,
|
||||||
|
userId: userId, username: username,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive);
|
||||||
|
|
||||||
|
var pctf_dto_list = _mapper.Map<IEnumerable<ProfileControlsTFDto>>(pctf_list);
|
||||||
|
|
||||||
|
return Result.Success(pctf_dto_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using DigitalData.Core.Abstractions.Application;
|
using DigitalData.Core.Abstractions.Application;
|
||||||
using DigitalData.Core.Application;
|
using DigitalData.Core.Application;
|
||||||
|
using DigitalData.Core.DTO;
|
||||||
using WorkFlow.Application.Contracts;
|
using WorkFlow.Application.Contracts;
|
||||||
using WorkFlow.Application.DTO.ProfileObjState;
|
using WorkFlow.Application.DTO.ProfileObjState;
|
||||||
using WorkFlow.Domain.Entities;
|
using WorkFlow.Domain.Entities;
|
||||||
@ -12,5 +13,20 @@ namespace WorkFlow.Application.Services
|
|||||||
: CRUDService<IProfileObjStateRepository, ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>(repository, mapper),
|
: CRUDService<IProfileObjStateRepository, ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>(repository, mapper),
|
||||||
IProfileObjStateService, ICRUDService<ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>
|
IProfileObjStateService, ICRUDService<ProfileObjStateCreateDto, ProfileObjStateDto, ProfileObjStateUpdateDto, ProfileObjState, int>
|
||||||
{
|
{
|
||||||
|
public async Task<DataResult<IEnumerable<ProfileObjStateDto>>> ReadAsync(
|
||||||
|
bool withProfile = true, bool withUser = true, bool withState = true,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
|
{
|
||||||
|
var pos_list = await _repository.ReadAsync(
|
||||||
|
isReadonly: true,
|
||||||
|
withProfile: withProfile, withUser: withUser, withState: withState,
|
||||||
|
userId: userId, username: username,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive);
|
||||||
|
|
||||||
|
var post_dto_list = _mapper.Map<IEnumerable<ProfileObjStateDto>>(pos_list);
|
||||||
|
|
||||||
|
return Result.Success(post_dto_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ namespace WorkFlow.Domain.Entities
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("USR_ID")]
|
[Column("USR_ID")]
|
||||||
public required int UsrId { get; init; }
|
public required int UserId { get; init; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("OBJ_ID")]
|
[Column("OBJ_ID")]
|
||||||
@ -62,7 +62,7 @@ namespace WorkFlow.Domain.Entities
|
|||||||
[ForeignKey("ProfileId")]
|
[ForeignKey("ProfileId")]
|
||||||
public Profile? Profile { get; init; } = default;
|
public Profile? Profile { get; init; } = default;
|
||||||
|
|
||||||
[ForeignKey("UsrId")]
|
[ForeignKey("UserId")]
|
||||||
public User? User { get; set; } = default;
|
public User? User { get; set; } = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ namespace WorkFlow.Domain.Entities
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("USR_ID")]
|
[Column("USR_ID")]
|
||||||
public required int UsrId { get; init; }
|
public required int UserId { get; init; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("OBJ_ID")]
|
[Column("OBJ_ID")]
|
||||||
@ -48,7 +48,7 @@ namespace WorkFlow.Domain.Entities
|
|||||||
[ForeignKey("ProfileId")]
|
[ForeignKey("ProfileId")]
|
||||||
public Profile? Profile { get; init; } = null;
|
public Profile? Profile { get; init; } = null;
|
||||||
|
|
||||||
[ForeignKey("UsrId")]
|
[ForeignKey("UserId")]
|
||||||
public User? User { get; init; } = null;
|
public User? User { get; init; } = null;
|
||||||
|
|
||||||
[ForeignKey("StateId")]
|
[ForeignKey("StateId")]
|
||||||
|
|||||||
@ -5,8 +5,10 @@ namespace WorkFlow.Infrastructure.Contracts
|
|||||||
{
|
{
|
||||||
public interface IProfileControlsTFRepository : ICRUDRepository<ProfileControlsTF, int>
|
public interface IProfileControlsTFRepository : ICRUDRepository<ProfileControlsTF, int>
|
||||||
{
|
{
|
||||||
Task<IEnumerable<ProfileControlsTF>> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = false, int? profileId = null, int? objId = null, bool? profileActive = null);
|
Task<IEnumerable<ProfileControlsTF>> ReadAsync(
|
||||||
|
bool isReadonly = true,
|
||||||
Task<ProfileControlsTF?> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = false, int? usrId = null, string? username = null, int? profileId = null, int? objId = null, bool? profileActive = null);
|
bool withProfile = true, bool withUser = false,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,8 +5,10 @@ namespace WorkFlow.Infrastructure.Contracts
|
|||||||
{
|
{
|
||||||
public interface IProfileObjStateRepository : ICRUDRepository<ProfileObjState, int>
|
public interface IProfileObjStateRepository : ICRUDRepository<ProfileObjState, int>
|
||||||
{
|
{
|
||||||
Task<IEnumerable<ProfileObjState>> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = true, bool withState = true, int? profileId = null, int? objId = null, bool? profileActive = null);
|
Task<IEnumerable<ProfileObjState>> ReadAsync(
|
||||||
|
bool isReadonly = true,
|
||||||
Task<ProfileObjState?> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = false, bool withState = true, int? usrId = null, string? username = null, int? profileId = null, int? objId = null, bool? profileActive = null);
|
bool withProfile = true, bool withUser = true, bool withState = true,
|
||||||
|
int? userId = null, string? username = null,
|
||||||
|
int? profileId = null, int? objId = null, bool? profileActive = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ using WorkFlow.Infrastructure.Contracts;
|
|||||||
|
|
||||||
namespace WorkFlow.Infrastructure.Repositories
|
namespace WorkFlow.Infrastructure.Repositories
|
||||||
{
|
{
|
||||||
|
//TODO: Make the db context type generic so that it can be used by other projects with different db contexts.
|
||||||
public class ConfigRepository(WFDBContext dbContext) : CRUDRepository<Config, int, WFDBContext>(dbContext, dbContext.Configs), IConfigRepository, ICRUDRepository<Config, int>
|
public class ConfigRepository(WFDBContext dbContext) : CRUDRepository<Config, int, WFDBContext>(dbContext, dbContext.Configs), IConfigRepository, ICRUDRepository<Config, int>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
{
|
{
|
||||||
protected override IQueryable<ProfileControlsTF> ReadOnly() => base.ReadOnly().Include(pctf => pctf.Profile).Include(pctf => pctf.User);
|
protected override IQueryable<ProfileControlsTF> ReadOnly() => base.ReadOnly().Include(pctf => pctf.Profile).Include(pctf => pctf.User);
|
||||||
|
|
||||||
protected IQueryable<ProfileControlsTF> Read(bool isReadonly = false, bool withProfile = true, bool withUser = true, int? profileId = null, int? usrId = null, string? username = null, int? objId = null, bool? profileActive = null)
|
protected IQueryable<ProfileControlsTF> Read(bool isReadonly = false, bool withProfile = true, bool withUser = true, int? profileId = null, int? userId = null, string? username = null, int? objId = null, bool? profileActive = null)
|
||||||
{
|
{
|
||||||
var query = isReadonly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
var query = isReadonly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
||||||
|
|
||||||
@ -23,8 +23,8 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
if (profileId is not null)
|
if (profileId is not null)
|
||||||
query = query.Where(pctf => pctf.ProfileId == profileId);
|
query = query.Where(pctf => pctf.ProfileId == profileId);
|
||||||
|
|
||||||
if (usrId is not null)
|
if (userId is not null)
|
||||||
query = query.Where(pctf => pctf.UsrId == usrId);
|
query = query.Where(pctf => pctf.UserId == userId);
|
||||||
|
|
||||||
if (username is null)
|
if (username is null)
|
||||||
query = query.Where(pctf => pctf.User!.Username == username);
|
query = query.Where(pctf => pctf.User!.Username == username);
|
||||||
@ -38,11 +38,16 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProfileControlsTF>> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = true, int? profileId = null, int? objId = null, bool? profileActive = null)
|
public async Task<IEnumerable<ProfileControlsTF>> ReadAsync(
|
||||||
=> await Read(isReadonly: isReadonly, withProfile: withProfile, withUser: withUser, profileId: profileId, objId: objId, profileActive: profileActive).ToListAsync();
|
bool isReadonly = true,
|
||||||
|
bool withProfile = true, bool withUser = true,
|
||||||
public async Task<ProfileControlsTF?> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = false, int? usrId = null, string? username = null, int? profileId = null, int? objId = null, bool? profileActive = null)
|
int? userId = null, string? username = null,
|
||||||
=> await Read(isReadonly: isReadonly, withProfile: withProfile, withUser: withUser, usrId: usrId, username: username, profileId: profileId, objId: objId, profileActive: profileActive)
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
.FirstOrDefaultAsync();
|
=> await Read(
|
||||||
|
isReadonly: isReadonly,
|
||||||
|
withProfile: withProfile, withUser: withUser,
|
||||||
|
userId: userId, username: username,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive)
|
||||||
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
{
|
{
|
||||||
protected override IQueryable<ProfileObjState> ReadOnly() => base.ReadOnly().Include(pos => pos.Profile).Include(pos => pos.State);
|
protected override IQueryable<ProfileObjState> ReadOnly() => base.ReadOnly().Include(pos => pos.Profile).Include(pos => pos.State);
|
||||||
|
|
||||||
protected IQueryable<ProfileObjState> Read(bool isReadonly = false, bool withProfile = true, bool withUser = true, bool withState = true, int? profileId = null, int? usrId = null, string? username = null, int? stateId = null, int? objId = null, bool? profileActive = null)
|
protected IQueryable<ProfileObjState> Read(bool isReadonly = false, bool withProfile = true, bool withUser = true, bool withState = true, int? profileId = null, int? userId = null, string? username = null, int? stateId = null, int? objId = null, bool? profileActive = null)
|
||||||
{
|
{
|
||||||
var query = isReadonly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
var query = isReadonly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
if (profileId is not null)
|
if (profileId is not null)
|
||||||
query = query.Where(pctf => pctf.ProfileId == profileId);
|
query = query.Where(pctf => pctf.ProfileId == profileId);
|
||||||
|
|
||||||
if (usrId is not null)
|
if (userId is not null)
|
||||||
query = query.Where(pctf => pctf.UsrId == usrId);
|
query = query.Where(pctf => pctf.UserId == userId);
|
||||||
|
|
||||||
if (username is null)
|
if (username is null)
|
||||||
query = query.Where(pctf => pctf.User!.Username == username);
|
query = query.Where(pctf => pctf.User!.Username == username);
|
||||||
@ -44,11 +44,16 @@ namespace WorkFlow.Infrastructure.Repositories
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProfileObjState>> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = true, bool withState = true, int? profileId = null, int? objId = null, bool? profileActive = null)
|
public async Task<IEnumerable<ProfileObjState>> ReadAsync(
|
||||||
=> await Read(isReadonly: isReadonly, withProfile: withProfile, withUser: withUser, withState: withState, profileId: profileId, objId: objId, profileActive: profileActive).ToListAsync();
|
bool isReadonly = true,
|
||||||
|
bool withProfile = true, bool withUser = true, bool withState = true,
|
||||||
public async Task<ProfileObjState?> ReadAsync(bool isReadonly = true, bool withProfile = true, bool withUser = false, bool withState = true, int? usrId = null, string? username = null, int? profileId = null, int? objId = null, bool? profileActive = null)
|
int? userId = null, string? username = null,
|
||||||
=> await Read(isReadonly: isReadonly, withProfile: withProfile, withUser: withUser, withState: withState, usrId: usrId, username: username, profileId: profileId, objId: objId, profileActive: profileActive)
|
int? profileId = null, int? objId = null, bool? profileActive = null)
|
||||||
.FirstOrDefaultAsync();
|
=> await Read(
|
||||||
|
isReadonly: isReadonly,
|
||||||
|
withProfile: withProfile, withUser: withUser, withState: withState,
|
||||||
|
userId: userId, username: username,
|
||||||
|
profileId: profileId, objId: objId, profileActive: profileActive)
|
||||||
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,9 +1,12 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using DigitalData.UserManager.Domain.Entities;
|
||||||
|
using DigitalData.UserManager.Infrastructure;
|
||||||
|
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using WorkFlow.Domain.Entities;
|
using WorkFlow.Domain.Entities;
|
||||||
|
|
||||||
namespace WorkFlow.Infrastructure
|
namespace WorkFlow.Infrastructure
|
||||||
{
|
{
|
||||||
public class WFDBContext(DbContextOptions options) : DbContext(options)
|
public class WFDBContext(DbContextOptions options) : DbContext(options), IUserManagerDbContext
|
||||||
{
|
{
|
||||||
public DbSet<Config> Configs { get; set; }
|
public DbSet<Config> Configs { get; set; }
|
||||||
|
|
||||||
@ -14,5 +17,25 @@ namespace WorkFlow.Infrastructure
|
|||||||
public DbSet<ProfileObjState> ProfileObjStates { get; set; }
|
public DbSet<ProfileObjState> ProfileObjStates { get; set; }
|
||||||
|
|
||||||
public DbSet<State> States { get; set; }
|
public DbSet<State> States { get; set; }
|
||||||
|
|
||||||
|
public DbSet<GroupOfUser> GroupOfUsers { get; set; }
|
||||||
|
|
||||||
|
public DbSet<Group> Groups { get; set; }
|
||||||
|
|
||||||
|
public DbSet<ModuleOfUser> ModuleOfUsers { get; set; }
|
||||||
|
|
||||||
|
public DbSet<Module> Modules { get; set; }
|
||||||
|
|
||||||
|
public DbSet<User> Users { get; set; }
|
||||||
|
|
||||||
|
public DbSet<UserRep> UserReps { get; set; }
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
//configure model builder for user manager tables
|
||||||
|
modelBuilder.ConfigureUserManager();
|
||||||
|
|
||||||
|
base.OnModelCreating(modelBuilder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.0" />
|
||||||
|
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkFlow.Infrastructure", "
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlow.Application", "WorkFlow.Application\WorkFlow.Application.csproj", "{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlow.Application", "WorkFlow.Application\WorkFlow.Application.csproj", "{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlow.API", "WorkFlow.API\WorkFlow.API.csproj", "{4FB33592-EF0D-47C3-9CDE-03B2EF12BE00}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -27,6 +29,10 @@ Global
|
|||||||
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5700B5DD-D17E-4E17-ADE5-48C95A0CC364}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4FB33592-EF0D-47C3-9CDE-03B2EF12BE00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4FB33592-EF0D-47C3-9CDE-03B2EF12BE00}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4FB33592-EF0D-47C3-9CDE-03B2EF12BE00}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4FB33592-EF0D-47C3-9CDE-03B2EF12BE00}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user