Compare commits
37 Commits
fbf9bbeba0
...
feat/authF
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1155cb406 | ||
|
|
9ae3345859 | ||
|
|
a4e4883d6b | ||
|
|
9f6acfb8d3 | ||
|
|
be78947b48 | ||
|
|
b2e64e794c | ||
|
|
d6b82cf085 | ||
|
|
6cd72fe755 | ||
|
|
8d0beab709 | ||
|
|
52871f006d | ||
|
|
ac064f4671 | ||
|
|
2d792c8544 | ||
|
|
239a5708a7 | ||
|
|
23283a6846 | ||
|
|
7d317308d5 | ||
|
|
2aab942563 | ||
|
|
054c91609e | ||
|
|
5c097eda80 | ||
|
|
d228a3cd50 | ||
|
|
0786013bd0 | ||
|
|
beabc3f4e0 | ||
|
|
44560e7057 | ||
|
|
2098a7d48d | ||
|
|
140f172369 | ||
|
|
b3e7c1aa99 | ||
|
|
0d4436b061 | ||
|
|
b88fd78367 | ||
|
|
7670f2119e | ||
|
|
a142196d87 | ||
|
|
59e8c6c0c6 | ||
|
|
3cf1215a1c | ||
|
|
81c00401b7 | ||
|
|
e86b42d955 | ||
|
|
80d28e12b9 | ||
|
|
7fc71f427b | ||
|
|
bd7d521c1e | ||
|
|
33326866f9 |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
12
DigitalData.UserManager.API/.config/dotnet-tools.json
Normal file
12
DigitalData.UserManager.API/.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "9.0.3",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +1,72 @@
|
||||
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.Mvc;
|
||||
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.UserManager.Application.Contracts;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using DigitalData.UserManager.Application;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace DigitalData.UserManager.API.Controllers
|
||||
namespace DigitalData.UserManager.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class AuthController : ControllerBase
|
||||
private readonly ILogger<UserController> _logger;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
|
||||
public AuthController(ILogger<UserController> logger, IUserService userService, IStringLocalizer<Resource> localizer)
|
||||
{
|
||||
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)
|
||||
_logger = logger;
|
||||
_userService = userService;
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("check")]
|
||||
public IActionResult CheckAuthentication() => Ok();
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost("login")]
|
||||
public Task<IActionResult> Login([FromBody] LogInDto login) => throw new NotImplementedException();
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("user")]
|
||||
public async Task<IActionResult> GetUserWithClaims()
|
||||
{
|
||||
try
|
||||
{
|
||||
_userService = userService;
|
||||
_gouService = gouService;
|
||||
_dirSearchService = directorySearchService;
|
||||
_localizer = localizer;
|
||||
_logger = logger;
|
||||
_config = configuration;
|
||||
}
|
||||
// Extract the username from the Name claim.
|
||||
string? username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(username))
|
||||
return Unauthorized();
|
||||
|
||||
[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)
|
||||
return await _userService.ReadByUsernameAsync(username)
|
||||
.ThenAsync(Ok, IActionResult (m, n) =>
|
||||
{
|
||||
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 ?? ""),
|
||||
new (ClaimTypes.Role, "PM_USER")
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
[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);
|
||||
}
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpPost("logout")]
|
||||
public IActionResult Logout()
|
||||
{
|
||||
Response.Cookies.Delete("AuthToken", new()
|
||||
{
|
||||
Path = "/"
|
||||
});
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>4.0.0.0</Version>
|
||||
<AssemblyVersion>4.0.0.0</AssemblyVersion>
|
||||
<FileVersion>4.0.0.0</FileVersion>
|
||||
<Version>6.0.1</Version>
|
||||
<AssemblyVersion>6.0.1</AssemblyVersion>
|
||||
<FileVersion>6.0.1</FileVersion>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -20,29 +21,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DigitalData.Core.API" Version="2.0.0" />
|
||||
<PackageReference Include="DigitalData.Auth.Client" Version="1.3.5" />
|
||||
<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" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.3.2" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.11" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Application\DigitalData.UserManager.Application.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -50,6 +42,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<None Include="wwwroot\assets\img\DD_white.svg" />
|
||||
<None Include="wwwroot\assets\img\digital_data.svg" />
|
||||
<None Include="wwwroot\assets\img\digital_data_red_BG.svg" />
|
||||
@@ -63,4 +59,8 @@
|
||||
<None Include="wwwroot\media\bootstrap-icons-X6UQXWUS.woff2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.DependencyInjection\DigitalData.UserManager.DependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
18
DigitalData.UserManager.API/LazyServiceProvider.cs
Normal file
18
DigitalData.UserManager.API/LazyServiceProvider.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace DigitalData.UserManager.API;
|
||||
|
||||
public class LazyServiceProvider : IServiceProvider
|
||||
{
|
||||
private Lazy<IServiceProvider>? _serviceProvider;
|
||||
|
||||
public Func<IServiceProvider> Factory
|
||||
{
|
||||
set => _serviceProvider = new(value);
|
||||
}
|
||||
|
||||
public object? GetService(Type serviceType)
|
||||
{
|
||||
if (_serviceProvider is null)
|
||||
throw new InvalidOperationException("GetService cannot be called before _serviceProvider is set.");
|
||||
return _serviceProvider.Value.GetService(serviceType);
|
||||
}
|
||||
}
|
||||
12
DigitalData.UserManager.API/Models/AuthTokenKeys.cs
Normal file
12
DigitalData.UserManager.API/Models/AuthTokenKeys.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace DigitalData.UserManager.API.Models;
|
||||
|
||||
public class AuthTokenKeys
|
||||
{
|
||||
public string Cookie { get; init; } = "AuthToken";
|
||||
|
||||
public string QueryString { get; init; } = "AuthToken";
|
||||
|
||||
public string Issuer { get; init; } = "auth.digitaldata.works";
|
||||
|
||||
public string Audience { get; init; } = "user-manager.digitaldata.works";
|
||||
}
|
||||
18
DigitalData.UserManager.API/Models/ModelExtensions.cs
Normal file
18
DigitalData.UserManager.API/Models/ModelExtensions.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace DigitalData.UserManager.API.Models;
|
||||
|
||||
public static class ModelExtensions
|
||||
{
|
||||
public static List<Claim> ToClaimList(this UserReadDto user) => new()
|
||||
{
|
||||
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 ?? "")
|
||||
};
|
||||
|
||||
public static Dictionary<string, object> ToClaimDictionary(this UserReadDto user) => user.ToClaimList().ToDictionary(claim => claim.Type, claim => (object)claim.Value);
|
||||
}
|
||||
@@ -10,20 +10,27 @@ using DigitalData.UserManager.API.Controllers;
|
||||
using DigitalData.UserManager.Application.Services;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using DigitalData.UserManager.API.Models;
|
||||
using DigitalData.Auth.Client;
|
||||
using DigitalData.UserManager.API;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DigitalData.Core.Abstractions.Security.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using DigitalData.UserManager.DependencyInjection;
|
||||
|
||||
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||
logger.Debug("init main");
|
||||
|
||||
try {
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
|
||||
var config = builder.Configuration;
|
||||
|
||||
builder.Services.AddEncryptor(builder.Configuration.GetSection("EncryptionParameters"));
|
||||
|
||||
if (builder.Configuration.GetValue<bool>("RunAsWindowsService"))
|
||||
builder.Host.UseWindowsService();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Host.UseNLog();
|
||||
|
||||
@@ -63,7 +70,7 @@ try {
|
||||
// Once the app is built, the password will be decrypted with Encryptor. lazy loading also acts as a call back method.
|
||||
Lazy<string>? cnn_str = null;
|
||||
|
||||
builder.Services.AddDbContext<UserManagerDbContext>(options => options.UseSqlServer(cnn_str!.Value).EnableSensitiveDataLogging());
|
||||
builder.Services.AddUserManager(options => options.UseSqlServer(cnn_str!.Value).EnableSensitiveDataLogging());
|
||||
|
||||
var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get<string[]>() ?? throw new InvalidOperationException("In appsettings there is no allowed origin.");
|
||||
|
||||
@@ -78,17 +85,93 @@ try {
|
||||
.AllowCredentials();
|
||||
});
|
||||
});
|
||||
|
||||
//builder.Services.AddAutoMapper(typeof(DirectoryMappingProfile).Assembly);
|
||||
builder.Services.AddUserManager<UserManagerDbContext>();
|
||||
|
||||
|
||||
builder.ConfigureBySection<DirectorySearchOptions>();
|
||||
builder.Services.AddDirectorySearchService();
|
||||
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
||||
builder.Services.AddJWTService<UserReadDto>(user => new SecurityTokenDescriptor()
|
||||
{
|
||||
Claims = user.ToClaimList().ToDictionary(claim => claim.Type, claim => claim.Value as object)
|
||||
});
|
||||
|
||||
var lazyProvider = new LazyServiceProvider();
|
||||
|
||||
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
|
||||
|
||||
var authTokenKeys = config.GetSection(nameof(AuthTokenKeys)).Get<AuthTokenKeys>() ?? new();
|
||||
|
||||
builder.Services
|
||||
.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddJwtBearer(opt =>
|
||||
{
|
||||
opt.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
|
||||
{
|
||||
var clientParams = lazyProvider.GetRequiredService<IOptions<ClientParams>>()?.Value;
|
||||
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
|
||||
return new List<SecurityKey>() { publicKey.SecurityKey };
|
||||
},
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = authTokenKeys.Issuer,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = authTokenKeys.Audience,
|
||||
};
|
||||
|
||||
opt.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
// if there is no token read related cookie or query string
|
||||
if (context.Token is null) // if there is no token
|
||||
{
|
||||
if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null)
|
||||
context.Token = cookieToken;
|
||||
else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken))
|
||||
context.Token = queryStrToken;
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
builder.Services.AddSwaggerGen(setupAct =>
|
||||
{
|
||||
setupAct.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT Authorization header using the Bearer scheme. Example: \"Bearer {token}\"",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "Bearer"
|
||||
});
|
||||
|
||||
setupAct.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
}
|
||||
},
|
||||
Array.Empty<string>()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddCookieBasedLocalizer();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
lazyProvider.Factory = () => app.Services;
|
||||
|
||||
cnn_str = new(() =>
|
||||
{
|
||||
var encryptor = app.Services.GetRequiredService<Encryptor>();
|
||||
|
||||
@@ -11,9 +11,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>07ccd651-647c-49f7-9715-30cebc13710d</ProjectGuid>
|
||||
<DesktopBuildPackageLocation>P:\Install .Net\0 DD - Smart UP\DD-UserManager\Web\${Version}\$(Version).zip</DesktopBuildPackageLocation>
|
||||
<DesktopBuildPackageLocation>P:\Install .Net\0 DD - Smart UP\DD-UserManager\Web\$(Version)\$(Version).zip</DesktopBuildPackageLocation>
|
||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||
<DeployIisAppPath>UserManager.API</DeployIisAppPath>
|
||||
<_TargetId>IISWebDeployPackage</_TargetId>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>Package</WebPublishMethod>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>07ccd651-647c-49f7-9715-30cebc13710d</ProjectGuid>
|
||||
<DesktopBuildPackageLocation>E:\TekH\Visual Studio\src\DigitalData.UserManager.API.zip</DesktopBuildPackageLocation>
|
||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||
<DeployIisAppPath>UserManager</DeployIisAppPath>
|
||||
<_TargetId>IISWebDeployPackage</_TargetId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -22,7 +22,7 @@
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchBrowser": false,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7103;http://localhost:5137",
|
||||
"environmentVariables": {
|
||||
|
||||
@@ -75,5 +75,16 @@
|
||||
"DateTimeZoneHandling": "Local",
|
||||
// Delete below in production
|
||||
"UseEncryptor": true,
|
||||
"UseSwagger": true
|
||||
"UseSwagger": true,
|
||||
"AuthClientParams": {
|
||||
"Url": "https://localhost:7192/auth-hub",
|
||||
"PublicKeys": [
|
||||
{
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "user-manager.digitaldata.works",
|
||||
"Content": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QCd7dH/xOUITFZbitMa/xnh8a0LyL6ZBvSRAwkI9ceplTRSHJXoM1oB+xtjWE1kOuHVLe941Tm03szS4+/rHIm0Ejva/KKlv7sPFAHE/pWuoPS303vOHgI4HAFcuwywA8CghUWzaaK5LU/Hl8srWwxBHv5hKIUjJFJygeAIENvFOZ1gFbB3MPEC99PiPOwAmfl4tMQUmSsFyspl/RWVi7bTv26ZE+m3KPcWppmvmYjXlSitxRaySxnfFvpca/qWfd/uUUg2KWKtpAwWVkqr0qD9v3TyKSgHoGDsrFpwSx8qufUJSinmZ1u/0iKl6TXeHubYS4C4SUSVjOWXymI2ZQIDAQAB-----END PUBLIC KEY-----"
|
||||
}
|
||||
],
|
||||
"RetryDelay": "00:00:05"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IClientUserRepository : ICRUDRepository<ClientUser, int>
|
||||
{
|
||||
Task<IEnumerable<ClientUser>> ReadAsync(bool readOnly = true, int? userId = null);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IGroupOfUserRepository : ICRUDRepository<GroupOfUser, int>
|
||||
{
|
||||
IQueryable<GroupOfUser> ReadByGroupId(int groupId);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByGroupUserIdAsync(int groupId, int userId);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithGroup();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithUser();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithGroupAndUser();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByUsernameAsync(string username);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByUserIdAsync(int userId);
|
||||
|
||||
// merge all GroupOfUserRepository-methods conditionally under this method
|
||||
Task<IEnumerable<GroupOfUser>> ReadAsync(
|
||||
bool readOnly = true,
|
||||
bool withGroup = true, bool withUser = true,
|
||||
int? id = null, int? groupId = null, int? userId = null, string? username = null);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IGroupRepository : ICRUDRepository<Group, int>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IModuleOfUserRepository : ICRUDRepository<ModuleOfUser, int>
|
||||
{
|
||||
IQueryable<ModuleOfUser> ReadByModuleId(int moduleId);
|
||||
|
||||
Task<IEnumerable<ModuleOfUser>> ReadByModelUserIdAsync(int moduleId, int userId);
|
||||
|
||||
Task<IEnumerable<ModuleOfUser>> ReadByUserAsync(string username);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IModuleRepository : ICRUDRepository<Module, int>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IUserRepRepository : ICRUDRepository<UserRep, int>
|
||||
{
|
||||
Task<IEnumerable<UserRep>> ReadAllAsync(
|
||||
bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false,
|
||||
int? userId = null, int? repUserId = null, int? groupId = null, int? repGroupId = null, bool readOnly = true);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
public interface IUserRepository : ICRUDRepository<User, int>
|
||||
{
|
||||
Task<IEnumerable<User>> ReadByModuleIdAsync(int moduleId);
|
||||
|
||||
Task<IEnumerable<User>> ReadUnassignedByModuleIdAsync(int moduleId);
|
||||
|
||||
Task<IEnumerable<User>> ReadByGroupIdAsync(int groupId);
|
||||
|
||||
Task<IEnumerable<User>> ReadUnassignedByGroupIdAsync(int groupId);
|
||||
|
||||
Task<User?> ReadByUsernameAsync(string username);
|
||||
}
|
||||
@@ -2,9 +2,6 @@
|
||||
using DigitalData.UserManager.Application.MappingProfiles;
|
||||
using DigitalData.UserManager.Application.Services;
|
||||
using DigitalData.UserManager.Application.Services.Options;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Infrastructure.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -19,8 +16,7 @@ namespace DigitalData.UserManager.Application
|
||||
/// <typeparam name="TDbContext">The type of the DbContext to use for the repositories.</typeparam>
|
||||
/// <param name="services">The IServiceCollection to which the services will be added.</param>
|
||||
/// <returns>The updated IServiceCollection.</returns>
|
||||
public static IServiceCollection AddUserManager<TDbContext>(this IServiceCollection services)
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
public static IServiceCollection AddUserManagerApplication(this IServiceCollection services)
|
||||
=> services
|
||||
.AddAutoMapper(typeof(UserMappingProfile).Assembly)
|
||||
.AddAutoMapper(typeof(GroupMappingProfile).Assembly)
|
||||
@@ -29,21 +25,13 @@ namespace DigitalData.UserManager.Application
|
||||
.AddAutoMapper(typeof(ModuleOfUserMappingProfile).Assembly)
|
||||
.AddAutoMapper(typeof(UserRepMappingProfile).Assembly)
|
||||
|
||||
.AddScoped<IUserRepository, UserRepository<TDbContext>>()
|
||||
.AddScoped<IGroupRepository, GroupRepository<TDbContext>>()
|
||||
.AddScoped<IGroupOfUserRepository, GroupOfUserRepository<TDbContext>>()
|
||||
.AddScoped<IModuleRepository, ModuleRepository<TDbContext>>()
|
||||
.AddScoped<IModuleOfUserRepository, ModuleOfUserRepository<TDbContext>>()
|
||||
.AddScoped<IUserRepRepository, UserRepRepository<TDbContext>>()
|
||||
.AddScoped<IClientUserRepository, ClientUserRepository<TDbContext>>()
|
||||
|
||||
.AddScoped<IUserService, UserService>()
|
||||
.AddScoped<IGroupService, GroupService>()
|
||||
.AddScoped<IGroupOfUserService, GroupOfUserService>()
|
||||
.AddScoped<IModuleService, ModuleService>()
|
||||
.AddScoped<IModuleOfUserService, ModuleOfUserService>()
|
||||
.AddScoped<IUserRepService, UserRepService>();
|
||||
|
||||
|
||||
public static IServiceCollection AddEncryptor(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<Encryptor>();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>UserManager.Application</PackageId>
|
||||
<Version>3.0.0</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>UserManager.Application</Product>
|
||||
@@ -14,20 +14,26 @@
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
|
||||
<PackageTags>digital data application user maanger</PackageTags>
|
||||
<AssemblyVersion>3.1.3</AssemblyVersion>
|
||||
<FileVersion>3.1.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.UserManager.Domain\Assets\icon.png">
|
||||
<None Include="..\Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<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.EmailProfilerDispatcher.Abstraction" Version="2.0.0" />
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.1" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
||||
@@ -35,16 +41,26 @@
|
||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Infrastructure\DigitalData.UserManager.Infrastructure.csproj" />
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices" Version="8.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.1" />
|
||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.4" />
|
||||
<PackageReference Include="System.DirectoryServices" Version="9.0.4" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.4" />
|
||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -3,7 +3,7 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.GroupOfUser;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
|
||||
@@ -3,15 +3,15 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.Group;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
public class GroupService : BaseService<IGroupRepository, GroupCreateDto, GroupReadDto, Group>, IGroupService
|
||||
{
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
public GroupService(IGroupRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper) : base(repository, mapper)
|
||||
private readonly IStringLocalizer<Resource>? _localizer;
|
||||
public GroupService(IGroupRepository repository, IMapper mapper, IStringLocalizer<Resource>? localizer = null) : base(repository, mapper)
|
||||
{
|
||||
_localizer = localizer;
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace DigitalData.UserManager.Application.Services
|
||||
group.AddedWho = user?.AddedWho ?? "UNAUTHORIZED";
|
||||
|
||||
if (await HasEntity(group.Id))
|
||||
return Result.Fail<int>().Message(_localizer[Key.GroupAlreadyExists.ToString()]);
|
||||
return Result.Fail<int>().Message(_localizer?[Key.GroupAlreadyExists].Value);
|
||||
|
||||
var createdGroup = await _repository.CreateAsync(group);
|
||||
if (createdGroup is null)
|
||||
|
||||
@@ -4,7 +4,7 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.ModuleOfUser;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using DigitalData.Core.Application;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.Module;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.UserRep;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
public class UserRepService : BaseService<IUserRepRepository, UserRepCreateDto, UserRepReadDto, UserRep>, IUserRepService
|
||||
{
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
public UserRepService(IUserRepRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper) : base(repository, mapper)
|
||||
private readonly IStringLocalizer<Resource>? _localizer;
|
||||
public UserRepService(IUserRepRepository repository, IMapper mapper, IStringLocalizer<Resource>? localizer = null) : base(repository, mapper)
|
||||
{
|
||||
_localizer = localizer;
|
||||
}
|
||||
@@ -27,10 +27,10 @@ namespace DigitalData.UserManager.Application.Services
|
||||
public override async Task<DataResult<int>> CreateAsync(UserRepCreateDto createDto)
|
||||
// XOR control
|
||||
=> (createDto.ValidFrom is null && createDto.ValidTo is not null) || (createDto.ValidFrom is not null && createDto.ValidTo is null)
|
||||
? Result.Fail<int>().Notice(LogLevel.None, Flag.DataIntegrityIssue, _localizer[Key.DateRangeNotXNOR])
|
||||
? Result.Fail<int>().Notice(LogLevel.None, Flag.DataIntegrityIssue, _localizer?[Key.DateRangeNotXNOR].Value)
|
||||
//date range control
|
||||
: (createDto.ValidFrom > createDto.ValidTo)
|
||||
? Result.Fail<int>().Notice(LogLevel.None, Flag.DataIntegrityIssue, _localizer[Key.InvalidDateRange])
|
||||
? Result.Fail<int>().Notice(LogLevel.None, Flag.DataIntegrityIssue, _localizer?[Key.InvalidDateRange].Value)
|
||||
: await base.CreateAsync(createDto);
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,15 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
public class UserService : BaseService<IUserRepository, UserCreateDto, UserReadDto, User>, IUserService
|
||||
{
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
public UserService(IUserRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper) : base(repository, mapper)
|
||||
private readonly IStringLocalizer<Resource>? _localizer;
|
||||
public UserService(IUserRepository repository, IMapper mapper, IStringLocalizer<Resource>? localizer = null) : base(repository, mapper)
|
||||
{
|
||||
_localizer = localizer;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace DigitalData.UserManager.Application.Services
|
||||
var user = _mapper.Map<User>(upDto);
|
||||
|
||||
if (await HasEntity(user.Id))
|
||||
return Result.Fail<int>().Message(_localizer[Key.UserAlreadyExists]);
|
||||
return Result.Fail<int>().Message(_localizer?[Key.UserAlreadyExists].Value);
|
||||
|
||||
//set the user
|
||||
var current_user = await GetUserAsync();
|
||||
@@ -66,7 +66,7 @@ namespace DigitalData.UserManager.Application.Services
|
||||
{
|
||||
var user = await _repository.ReadByUsernameAsync(username);
|
||||
if (user is null)
|
||||
return Result.Fail<UserReadDto>().Message(_localizer[Key.UserNotFoundInLocalDB]);
|
||||
return Result.Fail<UserReadDto>().Message(_localizer?[Key.UserNotFoundInLocalDB].Value);
|
||||
|
||||
var userDto = _mapper.Map<UserReadDto>(user);
|
||||
return Result.Success(userDto);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>UserManager</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>UserManager</Product>
|
||||
<Description>Die Hauptbibliothek, die Benutzer-, Gruppen- und Modulzuweisungen über Active Directory mit Entity Framework durchführt.</Description>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
|
||||
<PackageTags>digital data user maanger</PackageTags>
|
||||
<AssemblyVersion>1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Application\DigitalData.UserManager.Application.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Infrastructure\DigitalData.UserManager.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
25
DigitalData.UserManager.DependencyInjection/Extensions.cs
Normal file
25
DigitalData.UserManager.DependencyInjection/Extensions.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using DigitalData.UserManager.Application;
|
||||
using DigitalData.UserManager.Infrastructure;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DigitalData.UserManager.DependencyInjection;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static IServiceCollection AddUserManager<TDbContext>(this IServiceCollection services)
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
{
|
||||
services.AddUserManagerInfrastructure<TDbContext>();
|
||||
services.AddUserManagerApplication();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddUserManager(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction)
|
||||
{
|
||||
services.AddUserManagerInfrastructure(optionsAction);
|
||||
services.AddUserManagerApplication();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>UserManager.Domain</PackageId>
|
||||
<Version>3.0.0</Version>
|
||||
<Version>3.0.2</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>UserManager.Domain</Product>
|
||||
@@ -14,24 +14,19 @@
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
|
||||
<PackageTags>digital data domain user maanger</PackageTags>
|
||||
<AssemblyVersion>3.0.2</AssemblyVersion>
|
||||
<FileVersion>3.0.2</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.UserManager.Application\Assets\icon.png">
|
||||
<None Include="..\Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -1,10 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IClientUserRepository : ICRUDRepository<ClientUser, int>
|
||||
{
|
||||
Task<IEnumerable<ClientUser>> ReadAsync(bool readOnly = true, int? userId = null);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IGroupOfUserRepository : ICRUDRepository<GroupOfUser, int>
|
||||
{
|
||||
IQueryable<GroupOfUser> ReadByGroupId(int groupId);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByGroupUserIdAsync(int groupId, int userId);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithGroup();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithUser();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadAllAsyncWithGroupAndUser();
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByUsernameAsync(string username);
|
||||
|
||||
Task<IEnumerable<GroupOfUser>> ReadByUserIdAsync(int userId);
|
||||
|
||||
// merge all GroupOfUserRepository-methods conditionally under this method
|
||||
Task<IEnumerable<GroupOfUser>> ReadAsync(
|
||||
bool readOnly = true,
|
||||
bool withGroup = true, bool withUser = true,
|
||||
int? id = null, int? groupId = null, int? userId = null, string? username = null);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IGroupRepository : ICRUDRepository<Group, int>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IModuleOfUserRepository : ICRUDRepository<ModuleOfUser, int>
|
||||
{
|
||||
IQueryable<ModuleOfUser> ReadByModuleId(int moduleId);
|
||||
|
||||
Task<IEnumerable<ModuleOfUser>> ReadByModelUserIdAsync(int moduleId, int userId);
|
||||
|
||||
Task<IEnumerable<ModuleOfUser>> ReadByUserAsync(string username);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IModuleRepository : ICRUDRepository<Module, int>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,21 @@
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts;
|
||||
|
||||
public interface IUserManagerDbContext
|
||||
{
|
||||
public interface IUserManagerDbContext
|
||||
{
|
||||
public DbSet<GroupOfUser> GroupOfUsers { get; }
|
||||
public DbSet<GroupOfUser> GroupOfUsers { get; }
|
||||
|
||||
public DbSet<Group> Groups { get; }
|
||||
public DbSet<Group> Groups { get; }
|
||||
|
||||
public DbSet<ModuleOfUser> ModuleOfUsers { get; }
|
||||
public DbSet<ModuleOfUser> ModuleOfUsers { get; }
|
||||
|
||||
public DbSet<Module> Modules { get; }
|
||||
public DbSet<Module> Modules { get; }
|
||||
|
||||
public DbSet<User> Users { get; }
|
||||
public DbSet<User> Users { get; }
|
||||
|
||||
public DbSet<UserRep> UserReps { get; }
|
||||
public DbSet<UserRep> UserReps { get; }
|
||||
|
||||
public DbSet<ClientUser> ClientUsers { get; }
|
||||
}
|
||||
public DbSet<ClientUser> ClientUsers { get; }
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IUserRepRepository : ICRUDRepository<UserRep, int>
|
||||
{
|
||||
Task<IEnumerable<UserRep>> ReadAllAsync(
|
||||
bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false,
|
||||
int? userId = null, int? repUserId = null, int? groupId = null, int? repGroupId = null, bool readOnly = true);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Contracts
|
||||
{
|
||||
public interface IUserRepository : ICRUDRepository<User, int>
|
||||
{
|
||||
Task<IEnumerable<User>> ReadByModuleIdAsync(int moduleId);
|
||||
|
||||
Task<IEnumerable<User>> ReadUnassignedByModuleIdAsync(int moduleId);
|
||||
|
||||
Task<IEnumerable<User>> ReadByGroupIdAsync(int groupId);
|
||||
|
||||
Task<IEnumerable<User>> ReadUnassignedByGroupIdAsync(int groupId);
|
||||
|
||||
Task<User?> ReadByUsernameAsync(string username);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using DigitalData.UserManager.Application;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Infrastructure.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure;
|
||||
|
||||
public static class DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the UserManager repositories to the specified <see cref="IServiceCollection"/>.
|
||||
/// This method registers the necessary repositories for the UserManager.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDbContext">The type of the DbContext to use for the repositories.</typeparam>
|
||||
/// <param name="services">The IServiceCollection to which the services will be added.</param>
|
||||
/// <returns>The updated IServiceCollection.</returns>
|
||||
public static IServiceCollection AddUserManagerInfrastructure<TDbContext>(this IServiceCollection services)
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
{
|
||||
return services
|
||||
.AddScoped<IUserRepository, UserRepository<TDbContext>>()
|
||||
.AddScoped<IGroupRepository, GroupRepository<TDbContext>>()
|
||||
.AddScoped<IGroupOfUserRepository, GroupOfUserRepository<TDbContext>>()
|
||||
.AddScoped<IModuleRepository, ModuleRepository<TDbContext>>()
|
||||
.AddScoped<IModuleOfUserRepository, ModuleOfUserRepository<TDbContext>>()
|
||||
.AddScoped<IUserRepRepository, UserRepRepository<TDbContext>>()
|
||||
.AddScoped<IClientUserRepository, ClientUserRepository<TDbContext>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the UserManager services and repositories to the specified <see cref="IServiceCollection"/>.
|
||||
/// This method allows configuring the DbContext options using the provided <paramref name="optionsAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to which the services will be added.</param>
|
||||
/// <param name="optionsAction">An <see cref="Action{T}"/> to configure the <see cref="DbContextOptionsBuilder"/>.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
public static IServiceCollection AddUserManagerInfrastructure(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction) => services
|
||||
.AddDbContext<UserManagerDbContext>(optionsAction)
|
||||
.AddUserManagerInfrastructure<UserManagerDbContext>();
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>UserManager.Infrastructure</PackageId>
|
||||
<Version>3.0.0</Version>
|
||||
<Version>3.0.2</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>UserManager.Infrastructure</Product>
|
||||
@@ -14,34 +14,39 @@
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
|
||||
<PackageTags>digital data infrastructure user maanger</PackageTags>
|
||||
<AssemblyVersion>3.0.2</AssemblyVersion>
|
||||
<FileVersion>3.0.2</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.UserManager.Domain\Assets\icon.png">
|
||||
<None Include="..\Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.15" />
|
||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.20" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Application\DigitalData.UserManager.Application.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories;
|
||||
|
||||
public class ModuleOfUserRepository<TDbContext> : CRUDRepository<ModuleOfUser, int, TDbContext>, IModuleOfUserRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
{
|
||||
public class ModuleOfUserRepository<TDbContext> : CRUDRepository<ModuleOfUser, int, TDbContext>, IModuleOfUserRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
public ModuleOfUserRepository(TDbContext dbContext) : base(dbContext, dbContext.ModuleOfUsers)
|
||||
{
|
||||
public ModuleOfUserRepository(TDbContext dbContext) : base(dbContext, dbContext.ModuleOfUsers)
|
||||
{
|
||||
}
|
||||
|
||||
private IQueryable<ModuleOfUser> ReadByUser(string username)
|
||||
{
|
||||
return _dbSet.Where(mou => mou.User!.Username == username).Include(mou => mou.Module);
|
||||
}
|
||||
|
||||
public IQueryable<ModuleOfUser> ReadByModuleId(int moduleId)
|
||||
{
|
||||
return _dbSet.Where(mou => mou.ModuleId == moduleId);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ModuleOfUser>> ReadByModelUserIdAsync(int moduleId, int userId)
|
||||
{
|
||||
return await _dbSet.Where(mou => mou.ModuleId == moduleId && mou.UserId == userId).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ModuleOfUser>> ReadByUserAsync(string username) => await ReadByUser(username).ToListAsync();
|
||||
}
|
||||
|
||||
private IQueryable<ModuleOfUser> ReadByUser(string username)
|
||||
{
|
||||
return _dbSet.Where(mou => mou.User!.Username == username).Include(mou => mou.Module);
|
||||
}
|
||||
|
||||
public IQueryable<ModuleOfUser> ReadByModuleId(int moduleId)
|
||||
{
|
||||
return _dbSet.Where(mou => mou.ModuleId == moduleId);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ModuleOfUser>> ReadByModelUserIdAsync(int moduleId, int userId)
|
||||
{
|
||||
return await _dbSet.Where(mou => mou.ModuleId == moduleId && mou.UserId == userId).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ModuleOfUser>> ReadByUserAsync(string username) => await ReadByUser(username).ToListAsync();
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories;
|
||||
|
||||
public class ModuleRepository<TDbContext> : CRUDRepository<Module, int, TDbContext>, IModuleRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
{
|
||||
public class ModuleRepository<TDbContext> : CRUDRepository<Module, int, TDbContext>, IModuleRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
public ModuleRepository(TDbContext dbContext) : base(dbContext, dbContext.Modules)
|
||||
{
|
||||
public ModuleRepository(TDbContext dbContext) : base(dbContext, dbContext.Modules)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,48 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories
|
||||
namespace DigitalData.UserManager.Infrastructure.Repositories;
|
||||
|
||||
public class UserRepRepository<TDbContext> : CRUDRepository<UserRep, int, TDbContext>, IUserRepRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
{
|
||||
public class UserRepRepository<TDbContext> : CRUDRepository<UserRep, int, TDbContext>, IUserRepRepository
|
||||
where TDbContext : DbContext, IUserManagerDbContext
|
||||
public UserRepRepository(TDbContext dbContext) : base(dbContext, dbContext.UserReps)
|
||||
{
|
||||
public UserRepRepository(TDbContext dbContext) : base(dbContext, dbContext.UserReps)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<UserRep>> ReadAllAsync(
|
||||
bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false,
|
||||
int? userId = null, int? repUserId = null, int? groupId = null, int? repGroupId = null, bool readOnly = true)
|
||||
{
|
||||
var query = readOnly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
||||
public async Task<IEnumerable<UserRep>> ReadAllAsync(
|
||||
bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false,
|
||||
int? userId = null, int? repUserId = null, int? groupId = null, int? repGroupId = null, bool readOnly = true)
|
||||
{
|
||||
var query = readOnly ? _dbSet.AsNoTracking() : _dbSet.AsQueryable();
|
||||
|
||||
if (withUser)
|
||||
query = query.Include(ur => ur.User);
|
||||
if (withUser)
|
||||
query = query.Include(ur => ur.User);
|
||||
|
||||
if (withRepGroup)
|
||||
query = query.Include(ur => ur.RepGroup);
|
||||
if (withRepGroup)
|
||||
query = query.Include(ur => ur.RepGroup);
|
||||
|
||||
if (withGroup)
|
||||
query = query.Include(ur => ur.Group);
|
||||
if (withGroup)
|
||||
query = query.Include(ur => ur.Group);
|
||||
|
||||
if (withRepUser)
|
||||
query = query.Include(ur => ur.RepUser);
|
||||
if (withRepUser)
|
||||
query = query.Include(ur => ur.RepUser);
|
||||
|
||||
if (userId is not null)
|
||||
query = query.Where(ur => ur.UserId == userId);
|
||||
if (userId is not null)
|
||||
query = query.Where(ur => ur.UserId == userId);
|
||||
|
||||
if (repUserId is not null)
|
||||
query = query.Where(ur => ur.RepUserId == repUserId);
|
||||
if (repUserId is not null)
|
||||
query = query.Where(ur => ur.RepUserId == repUserId);
|
||||
|
||||
if (groupId is not null)
|
||||
query = query.Where(ur => ur.GroupId == groupId);
|
||||
if (groupId is not null)
|
||||
query = query.Where(ur => ur.GroupId == groupId);
|
||||
|
||||
if (repGroupId is not null)
|
||||
query = query.Where(ur => ur.RepGroupId == repGroupId);
|
||||
if (repGroupId is not null)
|
||||
query = query.Where(ur => ur.RepGroupId == repGroupId);
|
||||
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using DigitalData.UserManager.Application.Contracts.Repositories;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using DigitalData.UserManager.Infrastructure.Contracts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -11,32 +11,48 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Inf
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.API", "DigitalData.UserManager.API\DigitalData.UserManager.API.csproj", "{07CCD651-647C-49F7-9715-30CEBC13710D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.UserManager.DependencyInjection", "DigitalData.UserManager.DependencyInjection\DigitalData.UserManager.DependencyInjection.csproj", "{7E5FD115-EE6D-48F2-ACF1-E951EC071073}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assets", "Assets", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Assets\icon.png = Assets\icon.png
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BC8CEADC-F7D6-4469-8718-4B308C386B4D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0634853C-C515-48AF-8E27-E5CBF592BCE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1DD81373-82F9-4872-95C6-888624DB1797}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07CCD651-647C-49F7-9715-30CEBC13710D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07CCD651-647C-49F7-9715-30CEBC13710D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {6804DE1E-B257-4DC9-B9D4-08C8518C8282}
|
||||
EndGlobalSection
|
||||
|
||||
Reference in New Issue
Block a user