Auth commands and handlers, new and refactored

This commit is contained in:
Veljko Tosic
2026-02-14 18:46:54 +01:00
parent 068739c616
commit 62da4b7392
9 changed files with 124 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
using AipsCore.Application.Abstract.Command; using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Common.Authentication; using AipsCore.Application.Common.Authentication;
using AipsCore.Application.Common.Authentication.Dtos;
namespace AipsCore.Application.Models.User.Command.LogIn; namespace AipsCore.Application.Models.User.Command.LogIn;
public record LogInUserCommand(string Email, string Password) : ICommand<Token>; public record LogInUserCommand(string Email, string Password) : ICommand<LogInUserResultDto>;

View File

@@ -1,28 +1,40 @@
using AipsCore.Application.Abstract.Command; using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.UserContext; using AipsCore.Application.Abstract.UserContext;
using AipsCore.Application.Common.Authentication; using AipsCore.Application.Common.Authentication;
using AipsCore.Application.Common.Authentication.Dtos;
using AipsCore.Domain.Abstract; using AipsCore.Domain.Abstract;
using AipsCore.Domain.Models.User.External;
namespace AipsCore.Application.Models.User.Command.LogIn; namespace AipsCore.Application.Models.User.Command.LogIn;
public class LogInUserCommandHandler : ICommandHandler<LogInUserCommand, Token> public class LogInUserCommandHandler : ICommandHandler<LogInUserCommand, LogInUserResultDto>
{ {
private readonly IUserRepository _userRepository;
private readonly ITokenProvider _tokenProvider; private readonly ITokenProvider _tokenProvider;
private readonly IRefreshTokenRepository _refreshTokenRepository;
private readonly IAuthService _authService; private readonly IAuthService _authService;
private readonly IUnitOfWork _unitOfWork;
public LogInUserCommandHandler(IUserRepository userRepository, ITokenProvider tokenProvider, IAuthService authService) public LogInUserCommandHandler(
ITokenProvider tokenProvider,
IRefreshTokenRepository refreshTokenRepository,
IAuthService authService,
IUnitOfWork unitOfWork)
{ {
_userRepository = userRepository;
_tokenProvider = tokenProvider; _tokenProvider = tokenProvider;
_refreshTokenRepository = refreshTokenRepository;
_authService = authService; _authService = authService;
_unitOfWork = unitOfWork;
} }
public async Task<Token> Handle(LogInUserCommand command, CancellationToken cancellationToken = default) public async Task<LogInUserResultDto> Handle(LogInUserCommand command, CancellationToken cancellationToken = default)
{ {
var loginResult = await _authService.LoginWithEmailAndPasswordAsync(command.Email, command.Password, cancellationToken); var loginResult = await _authService.LoginWithEmailAndPasswordAsync(command.Email, command.Password, cancellationToken);
return new Token(_tokenProvider.Generate(loginResult.User, loginResult.Roles)); var accessToken = _tokenProvider.GenerateAccessToken(loginResult.User, loginResult.Roles);
var refreshToken = _tokenProvider.GenerateRefreshToken();
await _refreshTokenRepository.AddAsync(refreshToken, loginResult.User.Id, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
return new LogInUserResultDto(accessToken, refreshToken);
} }
} }

View File

@@ -0,0 +1,5 @@
using AipsCore.Application.Abstract.Command;
namespace AipsCore.Application.Models.User.Command.LogOut;
public record LogOutCommand(string RefreshToken) : ICommand;

View File

@@ -0,0 +1,19 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.UserContext;
namespace AipsCore.Application.Models.User.Command.LogOut;
public class LogOutCommandHandler : ICommandHandler<LogOutCommand>
{
private readonly IRefreshTokenRepository _refreshTokenRepository;
public LogOutCommandHandler(IRefreshTokenRepository refreshTokenRepository)
{
_refreshTokenRepository = refreshTokenRepository;
}
public async Task Handle(LogOutCommand command, CancellationToken cancellationToken = default)
{
await _refreshTokenRepository.RevokeAsync(command.RefreshToken, cancellationToken);
}
}

View File

@@ -0,0 +1,5 @@
using AipsCore.Application.Abstract.Command;
namespace AipsCore.Application.Models.User.Command.LogOutAll;
public record LogOutAllCommand : ICommand;

View File

@@ -0,0 +1,23 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.UserContext;
namespace AipsCore.Application.Models.User.Command.LogOutAll;
public class LogOutAllCommandHandler : ICommandHandler<LogOutAllCommand>
{
private readonly IRefreshTokenRepository _refreshTokenRepository;
private readonly IUserContext _userContext;
public LogOutAllCommandHandler(IRefreshTokenRepository refreshTokenRepository, IUserContext userContext)
{
_refreshTokenRepository = refreshTokenRepository;
_userContext = userContext;
}
public Task Handle(LogOutAllCommand command, CancellationToken cancellationToken = default)
{
var userId = _userContext.GetCurrentUserId();
return _refreshTokenRepository.RevokeAllAsync(userId, cancellationToken);
}
}

View File

@@ -0,0 +1,6 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Common.Authentication.Dtos;
namespace AipsCore.Application.Models.User.Command.RefreshLogIn;
public record RefreshLogInCommand(string RefreshToken) : ICommand<LogInUserResultDto>;

View File

@@ -0,0 +1,44 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.UserContext;
using AipsCore.Application.Common.Authentication;
using AipsCore.Application.Common.Authentication.Dtos;
using AipsCore.Domain.Abstract;
namespace AipsCore.Application.Models.User.Command.RefreshLogIn;
public class RefreshLogInCommandHandler : ICommandHandler<RefreshLogInCommand, LogInUserResultDto>
{
private readonly ITokenProvider _tokenProvider;
private readonly IRefreshTokenRepository _refreshTokenRepository;
private readonly IAuthService _authService;
private readonly IUnitOfWork _unitOfWork;
public RefreshLogInCommandHandler(
ITokenProvider tokenProvider,
IRefreshTokenRepository refreshTokenRepository,
IAuthService authService,
IUnitOfWork unitOfWork)
{
_tokenProvider = tokenProvider;
_refreshTokenRepository = refreshTokenRepository;
_authService = authService;
_unitOfWork = unitOfWork;
}
public async Task<LogInUserResultDto> Handle(RefreshLogInCommand command, CancellationToken cancellationToken = default)
{
var refreshToken = await _refreshTokenRepository.GetByValueAsync(command.RefreshToken, cancellationToken);
var loginResult = await _authService.LoginWithRefreshTokenAsync(refreshToken, cancellationToken);
var newAccessToken = _tokenProvider.GenerateAccessToken(loginResult.User, loginResult.Roles);
var newRefreshToken = _tokenProvider.GenerateRefreshToken();
await _refreshTokenRepository.RevokeAsync(refreshToken.Value, cancellationToken);
await _refreshTokenRepository.AddAsync(newRefreshToken, loginResult.User.Id, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
return new LogInUserResultDto(newAccessToken, newRefreshToken);
}
}

View File

@@ -1,19 +1,15 @@
using AipsCore.Application.Abstract.Command; using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Common.Authentication; using AipsCore.Application.Common.Authentication;
using AipsCore.Domain.Abstract;
using AipsCore.Domain.Models.User.External;
using AipsCore.Domain.Models.User.ValueObjects; using AipsCore.Domain.Models.User.ValueObjects;
namespace AipsCore.Application.Models.User.Command.SignUp; namespace AipsCore.Application.Models.User.Command.SignUp;
public class SignUpUserCommandHandler : ICommandHandler<SignUpUserCommand, UserId> public class SignUpUserCommandHandler : ICommandHandler<SignUpUserCommand, UserId>
{ {
private readonly IUserRepository _userRepository;
private readonly IAuthService _authService; private readonly IAuthService _authService;
public SignUpUserCommandHandler(IUserRepository userRepository, IAuthService authService) public SignUpUserCommandHandler(IAuthService authService)
{ {
_userRepository = userRepository;
_authService = authService; _authService = authService;
} }