Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
namespace Api.Controllers.Payload.Requests.Users;

public class GetAllEmployeesPaginatedQueryParameters : PaginatedQueryParameters
{

}
28 changes: 28 additions & 0 deletions src/Api/Controllers/UsersController.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,6 +8,7 @@
using Application.Users.Queries;
using Infrastructure.Identity.Authorization;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Security;

namespace Api.Controllers;

Expand DownExpand Up@@ -164,6 +165,33 @@ public async Task<ActionResult<Result<UserDto>>> Update([FromRoute] Guid userId,
}

/// <summary>
/// Get all users with the "Employee" role of the current user's department.
/// </summary>
/// <param name="queryParameters">Query parameters</param>
/// <returns>A list of UserDtos with the employee role of that department</returns>
[RequiresRole(IdentityData.Roles.Employee)]
[HttpGet("employees")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<Result<PaginatedList<UserDto>>>> GetAllEmployeesPaginated(
[FromQuery] GetAllEmployeesPaginatedQueryParameters queryParameters)
{
var performingUserDepartmentId = _currentUserService.GetDepartmentId();

if (performingUserDepartmentId is null)
{
throw new KeyNotFoundException("User does not belong to a department.");
}

var query = new GetAllEmployeesPaginated.Query()
{
DepartmentId = performingUserDepartmentId.Value,
}
var result = await Mediator.Send(query);
return Ok(Result<PaginatedList<UserDto>>.Succeed(result));
}

/// Get all user related logs paginated
/// </summary>
/// <param name="queryParameters">Get all users related logs query parameters</param>
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Services/CurrentUserService.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,7 +47,7 @@ public string GetRole()
var claim = _httpContextAccessor.HttpContext!.User.Claims
.FirstOrDefault(x => x.Type.Equals("departmentId"));
var id = claim?.Value;
return id is not null ? Guid.Parse(id) : null;
return id is not null && Guid.TryParse(id, out _) ? Guid.Parse(id) : null;
}

public User GetCurrentUser()
Expand Down
62 changes: 62 additions & 0 deletions src/Application/Users/Queries/GetAllEmployeesPaginated.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
using Application.Common.Extensions;
using Application.Common.Interfaces;
using Application.Common.Models;
using Application.Identity;
using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Application.Users.Queries;

public class GetAllEmployeesPaginated
{
public record Query : IRequest<PaginatedList<UserDto>>
{
public Guid DepartmentId { get; init; }
public int? Page { get; init; }
public int? Size { get; init; }
public string? SortBy { get; init; }
public string? SortOrder { get; init; }
}

public class Handler : IRequestHandler<Query, PaginatedList<UserDto>>
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;

public Handler(IApplicationDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public async Task<PaginatedList<UserDto>> Handle(Query request, CancellationToken cancellationToken)
{
var users = _context.Users.AsQueryable()
.Include(x => x.Department)
.Where(x => x.Department!.Id == request.DepartmentId
&& x.Role.Equals(IdentityData.Roles.Employee)
&& x.IsActive
&& x.IsActivated);

var sortBy = request.SortBy;
if (sortBy is null || !sortBy.MatchesPropertyName<UserDto>())
{
sortBy = nameof(UserDto.Id);
}
var sortOrder = request.SortOrder ?? "asc";
var pageNumber = request.Page is null or <= 0 ? 1 : request.Page;
var sizeNumber = request.Size is null or <= 0 ? 5 : request.Size;

var count = await users.CountAsync(cancellationToken);
var list = await users
.Paginate(pageNumber.Value, sizeNumber.Value)
.OrderByCustom(sortBy, sortOrder)
.ToListAsync(cancellationToken);

var result = _mapper.Map<List<UserDto>>(list);

return new PaginatedList<UserDto>(result, count, pageNumber.Value, sizeNumber.Value);
}
}
}
2 changes: 1 addition & 1 deletion src/Infrastructure/Identity/IdentityService.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -296,7 +296,7 @@ private SecurityToken CreateJweToken(User user)
new(JwtRegisteredClaimNames.Email, user.Email!),
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new(JwtRegisteredClaimNames.Iat, utcNow.ToString(CultureInfo.InvariantCulture)),
new("departmentId", user.Department!.Id.ToString()),
new("departmentId", user.Department is not null ? user.Department.Id.ToString() : String.Empty),
new("isActive", user.IsActive.ToString()),
};
var publicEncryptionKey = new RsaSecurityKey(_encryptionKey.ExportParameters(false)) {KeyId = _jweSettings.EncryptionKeyId};
Expand Down