Merge remote-tracking branch 'origin/master' into feature/oauth

# Conflicts:
#	src/Application/Common/Interfaces/IIdentityService.cs
#	src/Application/Users/Commands/CreateUser.cs
#	src/Infrastructure/Identity/IdentityService.cs
#	src/Infrastructure/Services/UserService.cs
#	src/Web/Program.cs
This commit is contained in:
Dominic Villemure
2024-06-09 18:05:49 -04:00
21 changed files with 259 additions and 61 deletions

View File

@@ -6,10 +6,15 @@ namespace Hutopy.Application.Common.Interfaces;
public interface IIdentityService
{
Task<string?> GetUserNameAsync(string userId);
Task<Result> CreateUserAsync(string email, string userName, string firstName, string lastName, string password);
Task<UserModel?> FindUserByIdAsync(string id);
Task<UserModel?> GetCurrentUserAsync();
Task<UserModel?> FindUserByEmailAsync(string id);
Task<UserModel?> GetUserByUserNameAsync(string userName);
Task<bool> IsInRoleAsync(string userId, string role);
Task<bool> AuthorizeAsync(string userId, string policyName);
Task<Result> AddRoleAsync(string userId, string role);
Task<IList<string>> GetCurrentUserRolesAsync();
Task<(Result Result, string UserId)> CreateUserAsync(string userName, string password);

View File

@@ -0,0 +1,10 @@
using Hutopy.Application.Common.Models;
namespace Hutopy.Application.Common.Interfaces;
public interface IRoleService
{
public Task<Result> CreateRoleAsync(string roleName);
public Task<Result> DeleteRoleAsync(string roleName);
public Task<RoleModel?> FindRoleByIdAsync(string roleId);
}

View File

@@ -0,0 +1,7 @@
namespace Hutopy.Application.Common.Models;
public class RoleModel
{
public string? Id { get; set; }
public string? Name { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace Hutopy.Application.Common.Models;
public class UserModel
{
public string? Id { get; set; }
public string? UserName { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? Email { get; set; }
}

View File

@@ -1,4 +1,5 @@
using System.Reflection;
using Hutopy.Application.Common.Behaviours;
using Microsoft.Extensions.DependencyInjection;
namespace Hutopy.Application;
@@ -15,7 +16,7 @@ public static class DependencyInjection
{
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
//cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehaviour<,>));
//cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehaviour<,>));
cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehaviour<,>));
//cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
//cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(PerformanceBehaviour<,>));
});

View File

@@ -2,9 +2,11 @@
using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Common.Mappings;
using Hutopy.Application.Common.Models;
using Hutopy.Application.Common.Security;
namespace Hutopy.Application.FutureCreators.Queries;
[Authorize(Roles = "Administrator")]
public record GetFutureCreatorListQuery : IRequest<PaginatedList<FutureCreatorListDto>>
{
public int PageNumber { get; init; } = 1;

View File

@@ -1,6 +1,4 @@
using System.Dynamic;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Domain.Interfaces;
using Hutopy.Application.Common.Interfaces;
namespace Hutopy.Application.Users.Commands;
public record CreateUserCommand : IRequest<Guid>
@@ -15,24 +13,22 @@ public record CreateUserCommand : IRequest<Guid>
public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, Guid>
{
private readonly IApplicationDbContext _context;
private readonly IUserService _userService;
private readonly IIdentityService _identityService;
public CreateUserCommandHandler(IApplicationDbContext context, IUserService userService)
public CreateUserCommandHandler(IApplicationDbContext context, IIdentityService identityService)
{
_context = context;
_userService = userService;
_identityService = identityService;
}
public async Task<Guid> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
// Dont really need the handler for the create. The get will work like this :
var user = await _userService.FindUserByIdAsync("072ae7d5-8c4a-4a0f-b250-7d39941125cb");
// var user2 = await _userService.FindUserByEmailAsync("test10@hotmail.com");
await _identityService.CreateUserAsync(request.EmailAddress, request.UserName, request.FirstName, request.LastName, request.Password);
var tt = user?.FirstName;
var user = await _identityService.FindUserByEmailAsync(request.EmailAddress);
await _context.SaveChangesAsync(cancellationToken);
return Guid.NewGuid();
return new Guid(user?.Id ?? string.Empty);
}
}

View File

@@ -1,34 +1,39 @@
using Hutopy.Application.Common.Interfaces;
using Hutopy.Domain.Interfaces;
namespace Hutopy.Application.Users.Queries;
namespace Hutopy.Application.Users.Queries.GetCurrentUser;
public record GetCurrentUserQuery : IRequest<UserDto>;
public class GetCurrentUserQueryHandler(
IApplicationDbContext context,
IMapper mapper,
IUserService userService
IIdentityService identityService
)
: IRequestHandler<GetCurrentUserQuery, UserDto>
{
public async Task<UserDto> Handle(GetCurrentUserQuery request, CancellationToken cancellationToken)
{
var identityUser = await userService.GetCurrentUserAsync();
var identityUser = await identityService.GetCurrentUserAsync();
var currentUserId = new Guid(identityUser?.Id ?? "");
var transactions = await context.UserTransactions
.Where(x => x.ApplicationUserId == currentUserId.ToString())
.OrderBy(x => x.LastModified)
.ProjectTo<UserTransactionDto>(mapper.ConfigurationProvider)
.Where(x => x.IsConfirmed == true)
.ToListAsync(cancellationToken);
var user = new UserDto()
var roles = await identityService.GetCurrentUserRolesAsync();
var user = new UserDto
{
Id = currentUserId,
FirstName = identityUser?.FirstName ?? "",
LastName = identityUser?.LastName ?? "",
UserTransactions = transactions
UserName =identityUser?.UserName ?? "",
UserTransactions = transactions,
TotalBalance = transactions.Sum(x => x.Amount),
UserRoles = roles
};
return user;

View File

@@ -1,13 +1,14 @@
namespace Hutopy.Application.Users.Queries;
namespace Hutopy.Application.Users.Queries.GetCurrentUser;
public class UserDto
{
public Guid Id { get; init; }
public required string FirstName { get; init; }
public required string LastName { get; init; }
public string UserName { get; init; } = String.Empty;
public List<UserTransactionDto> UserTransactions { get; init; } = [];
public IList<string> UserRoles { get; init; } = [];
public required decimal TotalBalance { get; init; }
}

View File

@@ -1,15 +1,18 @@
using Hutopy.Domain.Entities;
namespace Hutopy.Application.Users.Queries;
namespace Hutopy.Application.Users.Queries.GetCurrentUser;
public class UserTransactionDto
{
public required decimal Amount { get; init; }
public string Currency { get; init; } = "cad";
public string TipMessage { get; init; } = string.Empty;
public DateTimeOffset Created { get; init; }
public bool IsConfirmed { get; init; }
private class Mapping : Profile
{
public Mapping()

View File

@@ -1,4 +1,4 @@
using Hutopy.Domain.Interfaces;
using Hutopy.Application.Common.Interfaces;
namespace Hutopy.Application.Users.Queries.GetMinimalUser;
@@ -8,15 +8,15 @@ public record GetMinimalUserQuery : IRequest<MinimalUserDto>
};
public class GetMinimalUserQueryHandler(
IUserService userService
IIdentityService identityService
)
: IRequestHandler<GetMinimalUserQuery, MinimalUserDto>
{
public async Task<MinimalUserDto> Handle(GetMinimalUserQuery request, CancellationToken cancellationToken)
{
var identityUser = await userService.FindUserByIdAsync(request.UserId);
var identityUser = await identityService.FindUserByIdAsync(request.UserId);
var user = new MinimalUserDto()
var user = new MinimalUserDto
{
FirstName = identityUser?.FirstName ?? "",
LastName = identityUser?.LastName ?? "",