chore: aktualisierte DigitalData.Core-Pakete

This commit is contained in:
Developer 02 2025-03-24 14:17:23 +01:00
parent 59e8c6c0c6
commit a142196d87
14 changed files with 628 additions and 640 deletions

View File

@ -11,148 +11,147 @@ using DigitalData.Core.Abstractions.Application;
using Microsoft.Extensions.Localization;
using DigitalData.Core.DTO;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
[Route("api/[controller]")]
public class AuthController : ControllerBase
private readonly IUserService _userService;
private readonly IGroupOfUserService _gouService;
private readonly IDirectorySearchService _dirSearchService;
private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<AuthController> _logger;
private readonly IConfiguration _config;
public AuthController(IUserService userService, IGroupOfUserService gouService, IDirectorySearchService directorySearchService, IStringLocalizer<Resource> localizer, ILogger<AuthController> logger, IConfiguration configuration)
{
private readonly IUserService _userService;
private readonly IGroupOfUserService _gouService;
private readonly IDirectorySearchService _dirSearchService;
private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<AuthController> _logger;
private readonly IConfiguration _config;
public AuthController(IUserService userService, IGroupOfUserService gouService, IDirectorySearchService directorySearchService, IStringLocalizer<Resource> localizer, ILogger<AuthController> logger, IConfiguration configuration)
{
_userService = userService;
_gouService = gouService;
_dirSearchService = directorySearchService;
_localizer = localizer;
_logger = logger;
_config = configuration;
}
_userService = userService;
_gouService = gouService;
_dirSearchService = directorySearchService;
_localizer = localizer;
_logger = logger;
_config = configuration;
}
[AllowAnonymous]
[HttpGet("check")]
public IActionResult CheckAuthentication()
[AllowAnonymous]
[HttpGet("check")]
public IActionResult CheckAuthentication()
{
try
{
try
{
return Ok(User.Identity?.IsAuthenticated ?? false);
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
return Ok(User.Identity?.IsAuthenticated ?? false);
}
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LogInDto login)
catch(Exception ex)
{
try
_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 allowedGroupName = _config.GetSection("AllowedGroupName").Get<string>()
?? throw new InvalidOperationException("Allowed group names configuration is missing.");
var gouMsg = await _gouService.HasGroup(login.Username, allowedGroupName, 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)
{
bool isValid = _dirSearchService.ValidateCredentials(login.Username, login.Password);
return Unauthorized(uRes);
}
if (!isValid)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
UserReadDto user = uRes.Data;
var allowedGroupName = _config.GetSection("AllowedGroupName").Get<string>()
?? throw new InvalidOperationException("Allowed group names configuration is missing.");
// 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 ?? ""),
new (ClaimTypes.Role, "PM_USER")
};
var gouMsg = await _gouService.HasGroup(login.Username, allowedGroupName, 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);
}
// Create claimsIdentity
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
UserReadDto user = uRes.Data;
// Create claims
var claims = new List<Claim>
// Create authProperties
var authProperties = new AuthenticationProperties
{
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 ?? ""),
new (ClaimTypes.Role, "PM_USER")
IsPersistent = true,
AllowRefresh = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(60)
};
// Create claimsIdentity
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
// Sign in
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
// Create authProperties
var authProperties = new AuthenticationProperties
_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) =>
{
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);
}
_logger.LogNotice(n);
return NotFound(Result.Fail().Message(_localizer[Key.UserNotFound]));
});
}
[Authorize]
[HttpGet("user")]
public async Task<IActionResult> GetUserWithClaims()
catch (Exception ex)
{
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);
}
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout()
[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
try
{
try
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -7,41 +7,40 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class BaseAuthController<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TBaseEntity> : CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TBaseEntity, int>
where TCRUDService : IBaseService<TCreateDto, TReadDto, TBaseEntity>
where TCreateDto : BaseCreateDto
where TReadDto : class
where TUpdateDto : BaseUpdateDto
where TBaseEntity : BaseEntity
{
[Authorize]
public class BaseAuthController<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TBaseEntity> : CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TBaseEntity, int>
where TCRUDService : IBaseService<TCreateDto, TReadDto, TUpdateDto, TBaseEntity>
where TCreateDto : BaseCreateDto
where TReadDto : class
where TUpdateDto : BaseUpdateDto
where TBaseEntity : BaseEntity
private readonly Lazy<int?> _lUserId;
public BaseAuthController(ILogger logger, TCRUDService service, IUserService userService) : base(logger, service)
{
private readonly Lazy<int?> _lUserId;
public BaseAuthController(ILogger logger, TCRUDService service, IUserService userService) : base(logger, service)
_lUserId = new(() =>
{
_lUserId = new(() =>
{
var idSt = User.FindFirstValue(ClaimTypes.NameIdentifier);
bool hasId = int.TryParse(idSt, out int id);
return hasId ? id : null;
});
var idSt = User.FindFirstValue(ClaimTypes.NameIdentifier);
bool hasId = int.TryParse(idSt, out int id);
return hasId ? id : null;
});
service.UserFactoryAsync = async () =>
{
var id = _lUserId.Value;
service.UserFactoryAsync = async () =>
{
var id = _lUserId.Value;
return id is int intId
? await userService.ReadByIdAsync(intId).ThenAsync(
Success: res => res,
Fail: UserReadDto? (m, n) =>
{
_logger.LogNotice(n);
return null;
})
: null;
};
}
return id is int intId
? await userService.ReadByIdAsync(intId).ThenAsync(
Success: res => res,
Fail: UserReadDto? (m, n) =>
{
_logger.LogNotice(n);
return null;
})
: null;
};
}
}

View File

@ -10,226 +10,225 @@ using Microsoft.Extensions.Localization;
using DigitalData.Core.DTO;
using Microsoft.AspNetCore.Authorization;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Route("api/[controller]")]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
[Authorize]
public class DirectoryController : ControllerBase
{
[Route("api/[controller]")]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
[Authorize]
public class DirectoryController : ControllerBase
private readonly IUserService _userService;
private readonly IDirectorySearchService _dirSearchService;
private readonly Dictionary<string, string> _customSearchFilters;
private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<DirectoryController> _logger;
public DirectoryController(IConfiguration configuration, IStringLocalizer<Resource> localizer, IUserService userService, IDirectorySearchService directorySearchService, ILogger<DirectoryController> logger)
{
private readonly IUserService _userService;
private readonly IDirectorySearchService _dirSearchService;
private readonly Dictionary<string, string> _customSearchFilters;
private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<DirectoryController> _logger;
_localizer = localizer;
_userService = userService;
_dirSearchService = directorySearchService;
public DirectoryController(IConfiguration configuration, IStringLocalizer<Resource> localizer, IUserService userService, IDirectorySearchService directorySearchService, ILogger<DirectoryController> logger)
var customSearchFiltersSection = configuration.GetSection("DirectorySearch:CustomSearchFilters");
_customSearchFilters = customSearchFiltersSection.Get<Dictionary<string, string>>() ?? new();
_logger = logger;
}
[HttpGet("Root/{username}")]
public IActionResult GetRootOf(string username)
{
try
{
_localizer = localizer;
_userService = userService;
_dirSearchService = directorySearchService;
var root = _dirSearchService.GetSearchRootCache(username);
var customSearchFiltersSection = configuration.GetSection("DirectorySearch:CustomSearchFilters");
_customSearchFilters = customSearchFiltersSection.Get<Dictionary<string, string>>() ?? new();
_logger = logger;
return root is null ? NotFound() : Ok(new
{
guid = root.Guid,
nativeGuid = root.NativeGuid,
name = root.Name,
path = root.Path,
parentPath = root.Parent?.Path,
username = root.Username,
schemaClassName = root.SchemaClassName
});
}
[HttpGet("Root/{username}")]
public IActionResult GetRootOf(string username)
catch (Exception ex)
{
try
{
var root = _dirSearchService.GetSearchRootCache(username);
return root is null ? NotFound() : Ok(new
{
guid = root.Guid,
nativeGuid = root.NativeGuid,
name = root.Name,
path = root.Path,
parentPath = root.Parent?.Path,
username = root.Username,
schemaClassName = root.SchemaClassName
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("CustomSearchFilter")]
public IActionResult GetAllCustomFilters(string? filtername)
{
try
{
if (filtername is null)
{
return Ok(_customSearchFilters);
}
else
{
_dirSearchService.CustomSearchFilters.TryGetValue(filtername, out string? filter);
return filter is null ? NotFound() : Ok(filter);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("CreateSearchRoot")]
public async Task<IActionResult> CreateSearchRoot([FromBody] SearchRootCreateDto searchRootCreateDto)
{
try
{
var dirEntryUsername = searchRootCreateDto.DirEntryUsername ?? CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
bool isValid = _dirSearchService.ValidateCredentials(dirEntryUsername, searchRootCreateDto.DirEntryPassword);
if (!isValid)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
var userResult = await _userService.ReadByUsernameAsync(dirEntryUsername);
if (!userResult.IsSuccess || userResult.Data is null)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFoundInLocalDB]));
_dirSearchService.SetSearchRootCache(userResult.Data.Username, searchRootCreateDto.DirEntryPassword);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilter/{filter}")]
public IActionResult SearchByFilter([FromRoute] string filter, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilterName/{filterName}")]
public IActionResult SearchByFilterName([FromRoute] string filterName, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue(filterName, out string? filter);
if (filter is null)
return NotFound($"The filter named {filterName} does not exist.");
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Group")]
public IActionResult GetGroups(string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("Group", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP Group Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:Group to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("User")]
public IActionResult GetUsersByGroupName(string? dirEntryUsername, [FromQuery] string? groupName = null)
{
try
{
string[] propName = { "memberof", "samaccountname", "givenname", "sn", "mail" };
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("User", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP User Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:User to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(
Success: data =>
{
if (groupName is not null)
data = data
.Where(rp => rp.PropertyNames.Cast<string>().Contains("memberof") &&
rp["memberof"].Cast<string>().Any(ldapDir => ldapDir.Contains(groupName)))
.ToList();
return Ok(data);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
private string? CurrentUser
{
get => (HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value);
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("CustomSearchFilter")]
public IActionResult GetAllCustomFilters(string? filtername)
{
try
{
if (filtername is null)
{
return Ok(_customSearchFilters);
}
else
{
_dirSearchService.CustomSearchFilters.TryGetValue(filtername, out string? filter);
return filter is null ? NotFound() : Ok(filter);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("CreateSearchRoot")]
public async Task<IActionResult> CreateSearchRoot([FromBody] SearchRootCreateDto searchRootCreateDto)
{
try
{
var dirEntryUsername = searchRootCreateDto.DirEntryUsername ?? CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
bool isValid = _dirSearchService.ValidateCredentials(dirEntryUsername, searchRootCreateDto.DirEntryPassword);
if (!isValid)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
var userResult = await _userService.ReadByUsernameAsync(dirEntryUsername);
if (!userResult.IsSuccess || userResult.Data is null)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFoundInLocalDB]));
_dirSearchService.SetSearchRootCache(userResult.Data.Username, searchRootCreateDto.DirEntryPassword);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilter/{filter}")]
public IActionResult SearchByFilter([FromRoute] string filter, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilterName/{filterName}")]
public IActionResult SearchByFilterName([FromRoute] string filterName, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue(filterName, out string? filter);
if (filter is null)
return NotFound($"The filter named {filterName} does not exist.");
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Group")]
public IActionResult GetGroups(string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("Group", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP Group Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:Group to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("User")]
public IActionResult GetUsersByGroupName(string? dirEntryUsername, [FromQuery] string? groupName = null)
{
try
{
string[] propName = { "memberof", "samaccountname", "givenname", "sn", "mail" };
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("User", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP User Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:User to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(
Success: data =>
{
if (groupName is not null)
data = data
.Where(rp => rp.PropertyNames.Cast<string>().Contains("memberof") &&
rp["memberof"].Cast<string>().Any(ldapDir => ldapDir.Contains(groupName)))
.ToList();
return Ok(data);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
private string? CurrentUser
{
get => (HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value);
}
}

View File

@ -1,46 +1,44 @@
using DigitalData.UserManager.Application.Services;
using DigitalData.UserManager.Application.Services.Options;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Route("api/[controller]")]
[ApiController]
public class EncryptionController : ControllerBase
{
[Route("api/[controller]")]
[ApiController]
public class EncryptionController : ControllerBase
private readonly Encryptor _encryptor;
public EncryptionController(Encryptor encryptor)
{
private readonly Encryptor _encryptor;
_encryptor = encryptor;
}
public EncryptionController(Encryptor encryptor)
{
_encryptor = encryptor;
}
[HttpPost("encrypt")]
public IActionResult Encrypt([FromQuery] string plainText, [FromBody] EncryptionParameters? options = null)
{
string cipherText = options is null
? _encryptor.Encrypt(plainText)
: Encryptor.Encrypt(plainText, options.Key, options.IV);
[HttpPost("encrypt")]
public IActionResult Encrypt([FromQuery] string plainText, [FromBody] EncryptionParameters? options = null)
{
string cipherText = options is null
? _encryptor.Encrypt(plainText)
: Encryptor.Encrypt(plainText, options.Key, options.IV);
return Ok(cipherText);
}
return Ok(cipherText);
}
[HttpPost("decrypt")]
public IActionResult Decrypt([FromQuery] string cipherText, [FromBody] EncryptionParameters? options = null)
{
var plainText = options is null
? _encryptor.Decrypt(cipherText)
: Encryptor.Decrypt(cipherText, options.Key, options.IV);
[HttpPost("decrypt")]
public IActionResult Decrypt([FromQuery] string cipherText, [FromBody] EncryptionParameters? options = null)
{
var plainText = options is null
? _encryptor.Decrypt(cipherText)
: Encryptor.Decrypt(cipherText, options.Key, options.IV);
return Ok(plainText);
}
return Ok(plainText);
}
[HttpGet]
public IActionResult Generate()
{
var param = Encryptor.GenerateParameters();
return Ok(param);
}
[HttpGet]
public IActionResult Generate()
{
var param = Encryptor.GenerateParameters();
return Ok(param);
}
}

View File

@ -5,39 +5,38 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers
{
[Authorize]
public class GroupController : BaseAuthController<IGroupService, GroupCreateDto, GroupReadDto, GroupUpdateDto, Group>
{
public GroupController(ILogger<GroupController> logger, IGroupService service, IUserService userService) : base(logger, service, userService)
{
}
namespace DigitalData.UserManager.API.Controllers;
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(DirectoryGroupDto adGroup)
[Authorize]
public class GroupController : BaseAuthController<IGroupService, GroupCreateDto, GroupReadDto, GroupUpdateDto, Group>
{
public GroupController(ILogger<GroupController> logger, IGroupService service, IUserService userService) : base(logger, service, userService)
{
}
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(DirectoryGroupDto adGroup)
{
try
{
try
{
return await _service.CreateAsync(adGroup).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
return await _service.CreateAsync(adGroup).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -5,77 +5,76 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class GroupOfUserController : BaseAuthController<IGroupOfUserService, GroupOfUserCreateDto, GroupOfUserReadDto, GroupOfUserUpdateDto, GroupOfUser>
{
[Authorize]
public class GroupOfUserController : BaseAuthController<IGroupOfUserService, GroupOfUserCreateDto, GroupOfUserReadDto, GroupOfUserUpdateDto, GroupOfUser>
public GroupOfUserController(ILogger<GroupOfUserController> logger, IGroupOfUserService service, IUserService userService) : base(logger, service, userService)
{
public GroupOfUserController(ILogger<GroupOfUserController> logger, IGroupOfUserService service, IUserService userService) : base(logger, service, userService)
}
[HttpDelete]
public async Task<IActionResult> Delete([FromQuery] int groupId, [FromQuery] int userId)
{
try
{
}
[HttpDelete]
public async Task<IActionResult> Delete([FromQuery] int groupId, [FromQuery] int userId)
{
try
return await _service.DeleteAsyncByGroupUserId(groupId, userId).ThenAsync(Ok, IActionResult (m, n) =>
{
return await _service.DeleteAsyncByGroupUserId(groupId, userId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
}
});
}
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
[HttpGet]
public async Task<IActionResult> GetAll([FromQuery]bool withUser = false, [FromQuery]bool withGroup = false, [FromQuery] string? username = null)
catch (Exception ex)
{
try
{
if (username is not null)
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
return await _service.ReadAllAsyncWith(withUser, withGroup).ThenAsync(Ok, IActionResult (m, n) =>
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
[HttpGet]
public async Task<IActionResult> GetAll([FromQuery]bool withUser = false, [FromQuery]bool withGroup = false, [FromQuery] string? username = null)
{
try
{
if (username is not null)
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Has")]
public async Task<IActionResult> HasGroup([FromQuery] string username, [FromQuery] string groupname)
return await _service.ReadAllAsyncWith(withUser, withGroup).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
catch(Exception ex)
{
try
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Has")]
public async Task<IActionResult> HasGroup([FromQuery] string username, [FromQuery] string groupname)
{
try
{
return await _service.HasGroup(username, groupname).ThenAsync(Ok, (m, n) =>
{
return await _service.HasGroup(username, groupname).ThenAsync(Ok, (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
}
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -4,13 +4,12 @@ using DigitalData.UserManager.Application.DTOs.Module;
using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class ModuleController : ReadControllerBaseWithErrorHandling<IModuleService, ModuleDto, Module, int>
{
[Authorize]
public class ModuleController : ReadControllerBaseWithErrorHandling<IModuleService, ModuleDto, Module, int>
public ModuleController(ILogger<ModuleController> logger, IModuleService service) : base(logger, service)
{
public ModuleController(ILogger<ModuleController> logger, IModuleService service) : base(logger, service)
{
}
}
}

View File

@ -6,48 +6,47 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class ModuleOfUserController : CRUDControllerBaseWithErrorHandling<IModuleOfUserService, ModuleOfUserCreateDto, ModuleOfUserReadDto, ModuleOfUserUpdateDto, ModuleOfUser, int>
{
[Authorize]
public class ModuleOfUserController : CRUDControllerBaseWithErrorHandling<IModuleOfUserService, ModuleOfUserCreateDto, ModuleOfUserReadDto, ModuleOfUserUpdateDto, ModuleOfUser, int>
public ModuleOfUserController(ILogger<ModuleOfUserController> logger, IModuleOfUserService service) : base(logger, service)
{
public ModuleOfUserController(ILogger<ModuleOfUserController> logger, IModuleOfUserService service) : base(logger, service)
{
}
}
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
[HttpGet]
public async Task<IActionResult> GetAll(string? username = null)
{
[HttpGet]
public async Task<IActionResult> GetAll(string? username = null)
{
if (username is not null)
return await _service.ReadByUserAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
return await base.GetAll();
}
[HttpDelete]
public async Task<IActionResult> Delete([FromQuery] int moduleId, [FromQuery]int userId)
{
try
if (username is not null)
return await _service.ReadByUserAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
return await _service.DeleteAsyncByModuleUserId(moduleId, userId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
}
});
return await base.GetAll();
}
[HttpDelete]
public async Task<IActionResult> Delete([FromQuery] int moduleId, [FromQuery]int userId)
{
try
{
return await _service.DeleteAsyncByModuleUserId(moduleId, userId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -1,4 +1,3 @@
using DigitalData.Core.API;
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.User;
@ -6,95 +5,94 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class UserController : BaseAuthController<IUserService, UserCreateDto, UserReadDto, UserUpdateDto, User>
{
[Authorize]
public class UserController : BaseAuthController<IUserService, UserCreateDto, UserReadDto, UserUpdateDto, User>
public UserController(ILogger<UserController> logger, IUserService service) : base(logger, service, service)
{
public UserController(ILogger<UserController> logger, IUserService service) : base(logger, service, service)
{
}
}
[HttpGet("ByModuleId/{moduleId}")]
public async Task<IActionResult> GetByModuleId([FromRoute] int moduleId, [FromQuery]bool assigned = true)
[HttpGet("ByModuleId/{moduleId}")]
public async Task<IActionResult> GetByModuleId([FromRoute] int moduleId, [FromQuery]bool assigned = true)
{
try
{
try
{
return await (assigned ? _service.ReadByModuleIdAsync(moduleId) : _service.ReadUnassignedByModuleIdAsync(moduleId))
.ThenAsync(Ok, IActionResult(m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByGroupId/{groupId}")]
public async Task<IActionResult> GetByGroupId([FromRoute] int groupId, [FromQuery] bool assigned = true)
{
try
{
return await (assigned ? _service.ReadByGroupIdAsync(groupId) : _service.ReadUnassignedByGroupIdAsync(groupId))
.ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(UserPrincipalDto upDto)
{
try
{
return await _service.CreateAsync(upDto).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByUsername/{username}")]
public virtual async Task<IActionResult> GetByUsername([FromRoute] string username)
{
try
{
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
return await (assigned ? _service.ReadByModuleIdAsync(moduleId) : _service.ReadUnassignedByModuleIdAsync(moduleId))
.ThenAsync(Ok, IActionResult(m, n) =>
{
_logger.LogNotice(n);
return NotFound();
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByGroupId/{groupId}")]
public async Task<IActionResult> GetByGroupId([FromRoute] int groupId, [FromQuery] bool assigned = true)
{
try
{
return await (assigned ? _service.ReadByGroupIdAsync(groupId) : _service.ReadUnassignedByGroupIdAsync(groupId))
.ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(UserPrincipalDto upDto)
{
try
{
return await _service.CreateAsync(upDto).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByUsername/{username}")]
public virtual async Task<IActionResult> GetByUsername([FromRoute] string username)
{
try
{
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
_logger.LogNotice(n);
return NotFound();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -5,38 +5,37 @@ using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers
{
[Authorize]
public class UserRepController : BaseAuthController<IUserRepService, UserRepCreateDto, UserRepReadDto, UserRepUpdateDto, UserRep>
{
public UserRepController(ILogger<UserRepController> logger, IUserRepService service, IUserService userService) : base(logger, service, userService)
{
}
namespace DigitalData.UserManager.API.Controllers;
[NonAction]
public override Task<IActionResult> GetAll()
[Authorize]
public class UserRepController : BaseAuthController<IUserRepService, UserRepCreateDto, UserRepReadDto, UserRepUpdateDto, UserRep>
{
public UserRepController(ILogger<UserRepController> logger, IUserRepService service, IUserService userService) : base(logger, service, userService)
{
}
[NonAction]
public override Task<IActionResult> GetAll()
{
return base.GetAll();
}
[HttpGet]
public async Task<IActionResult> GetAll(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null)
{
try
{
return base.GetAll();
return await _service.ReadAllAsync(withUser: withUser, withRepGroup: withRepGroup, withGroup: withGroup, withRepUser: withRepUser,
userId: userId, groupId: groupId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
[HttpGet]
public async Task<IActionResult> GetAll(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null)
catch (Exception ex)
{
try
{
return await _service.ReadAllAsync(withUser: withUser, withRepGroup: withRepGroup, withGroup: withGroup, withRepUser: withRepUser,
userId: userId, groupId: groupId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@ -20,7 +20,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DigitalData.Core.API" Version="2.0.0" />
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.20" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />

View File

@ -83,7 +83,7 @@ try {
builder.Services.AddUserManager<UserManagerDbContext>();
builder.ConfigureBySection<DirectorySearchOptions>();
builder.Services.AddDirectorySearchService();
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
builder.Services.AddCookieBasedLocalizer();

View File

@ -27,8 +27,8 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.1.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.0.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.0" />
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />

View File

@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.1.0" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.0" />
</ItemGroup>
<ItemGroup>