Commit d739d7b0 authored by Almouhannad's avatar Almouhannad

(B) Add login result

parent 64f73a76
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace Application.Users.Commands.Login; namespace Application.Users.Commands.Login;
public class LoginCommand : ICommand<string> public class LoginCommand : ICommand<LoginResponse>
{ {
public string UserName { get; set; } = null!; public string UserName { get; set; } = null!;
public string Password { get; set; } = null!; public string Password { get; set; } = null!;
......
using Application.Abstractions.CQRS.Commands; using Application.Abstractions.CQRS.Commands;
using Application.Abstractions.JWT; using Application.Abstractions.JWT;
using Domain.Entities.Identity.UserRoles;
using Domain.Entities.Identity.Users; using Domain.Entities.Identity.Users;
using Domain.Errors; using Domain.Errors;
using Domain.Repositories; using Domain.Repositories;
...@@ -8,7 +9,7 @@ using Domain.UnitOfWork; ...@@ -8,7 +9,7 @@ using Domain.UnitOfWork;
namespace Application.Users.Commands.Login; namespace Application.Users.Commands.Login;
public class LoginCommandHandler : CommandHandlerBase<LoginCommand, string> public class LoginCommandHandler : CommandHandlerBase<LoginCommand, LoginResponse>
{ {
#region CTOR DI #region CTOR DI
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
...@@ -20,16 +21,16 @@ public class LoginCommandHandler : CommandHandlerBase<LoginCommand, string> ...@@ -20,16 +21,16 @@ public class LoginCommandHandler : CommandHandlerBase<LoginCommand, string>
} }
#endregion #endregion
public override async Task<Result<string>> HandleHelper(LoginCommand request, CancellationToken cancellationToken) public override async Task<Result<LoginResponse>> HandleHelper(LoginCommand request, CancellationToken cancellationToken)
{ {
#region 1. Check username and password are correct #region 1. Check username and password are correct
Result<User?> loginResult = await _userRepository.VerifyPasswordAsync(request.UserName, request.Password); Result<User?> loginResult = await _userRepository.VerifyPasswordAsync(request.UserName, request.Password);
if (loginResult.IsFailure) if (loginResult.IsFailure)
return Result.Failure<string>(loginResult.Error); // Not found username return Result.Failure<LoginResponse>(loginResult.Error); // Not found username
if (loginResult.Value is null) // Invalid password if (loginResult.Value is null) // Invalid password
return Result.Failure<string>(IdentityErrors.PasswordMismatch); return Result.Failure<LoginResponse>(IdentityErrors.PasswordMismatch);
#endregion #endregion
#region 2. Generate JWT #region 2. Generate JWT
...@@ -37,7 +38,40 @@ public class LoginCommandHandler : CommandHandlerBase<LoginCommand, string> ...@@ -37,7 +38,40 @@ public class LoginCommandHandler : CommandHandlerBase<LoginCommand, string>
string token = _jwtProvider.Generate(user); string token = _jwtProvider.Generate(user);
#endregion #endregion
return Result.Success<string>(token); #region 3. Generate Response
#region 3.1. Admin
if (user.Role == Roles.Admin)
{
return LoginResponse.GetResponse(user, token);
}
#endregion
#region 3.2. Doctor
if (user.Role == Roles.Doctor)
{
var doctorUserResult = await _userRepository.GetDoctorUserByUserNameFullAsync(user.UserName);
if (doctorUserResult.IsFailure)
return Result.Failure<LoginResponse>(doctorUserResult.Error);
return LoginResponse.GetResponse(doctorUserResult.Value.User, token, doctorUserResult.Value.Doctor.PersonalInfo);
}
#endregion
#region 3.3. Receptionist user
if (user.Role == Roles.Receptionist)
{
var receptionistUser = await _userRepository.GetReceptionistUserByUserNameFullAsync(user.UserName);
if (receptionistUser.IsFailure)
return Result.Failure<LoginResponse>(receptionistUser.Error);
return LoginResponse.GetResponse(receptionistUser.Value.User, token, receptionistUser.Value.PersonalInfo);
}
#endregion
return Result.Failure<LoginResponse>(IdentityErrors.NotFound);
#endregion
} }
......
using Domain.Entities.Identity.UserRoles;
using Domain.Entities.Identity.Users;
using Domain.Entities.People.Shared;
using Domain.Errors;
using Domain.Shared;
namespace Application.Users.Commands.Login;
public class LoginResponse
{
public int Id { get; set; }
public string UserName { get; set; } = null!;
public string JWT { get; set; } = null!;
public PersonalInfo? PersonalInfo { get; set; } = null;
public static Result<LoginResponse> GetResponse(User user, string jwt, PersonalInfo? personalInfo = null)
{
var response = new LoginResponse
{
Id = user.Id,
UserName = user.UserName,
JWT = jwt
};
if (personalInfo is null)
{
if (user.Role != Roles.Admin)
return Result.Failure<LoginResponse>(IdentityErrors.NotFound);
response.PersonalInfo = PersonalInfo.Create("admin", "", "").Value;
return response;
}
response.PersonalInfo = personalInfo;
return response;
}
}
...@@ -10,4 +10,7 @@ public interface IUserRepository : IRepository<User> ...@@ -10,4 +10,7 @@ public interface IUserRepository : IRepository<User>
public Task<Result<User>> GetByUserNameFullAsync(string userName); public Task<Result<User>> GetByUserNameFullAsync(string userName);
public Task<Result<User?>> VerifyPasswordAsync(string userName, string password); public Task<Result<User?>> VerifyPasswordAsync(string userName, string password);
public Task<Result<DoctorUser>> GetDoctorUserByUserNameFullAsync(string userName);
public Task<Result<ReceptionistUser>> GetReceptionistUserByUserNameFullAsync(string userName);
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
using Persistence.Repositories.Specifications.Base; using Persistence.Repositories.Specifications.Base;
using System.Linq.Expressions; using System.Linq.Expressions;
namespace Persistence.Repositories.Users; namespace Persistence.Repositories.Users.Specifications;
public class FullUserSpecification : Specification<User> public class FullUserSpecification : Specification<User>
{ {
......
...@@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; ...@@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Persistence.Context; using Persistence.Context;
using Persistence.Identity.PasswordsHashing; using Persistence.Identity.PasswordsHashing;
using Persistence.Repositories.Base; using Persistence.Repositories.Base;
using Persistence.Repositories.Users.Specifications;
namespace Persistence.Repositories.Users; namespace Persistence.Repositories.Users;
...@@ -56,4 +57,43 @@ public class UserRepository : Repositroy<User>, IUserRepository ...@@ -56,4 +57,43 @@ public class UserRepository : Repositroy<User>, IUserRepository
} }
#endregion #endregion
#region Get doctor user by user name full
public async Task<Result<DoctorUser>> GetDoctorUserByUserNameFullAsync(string username)
{
// This is a multi level query, so using specification pattern in this case is useless
var query
= _context.Set<DoctorUser>()
.Include(doctroUser => doctroUser.User)
.ThenInclude(user => user.Role)
.Where(doctorUser => doctorUser.User.UserName == username)
.Include(doctorUser => doctorUser.Doctor)
.ThenInclude(doctor => doctor.PersonalInfo);
var result = await query.ToListAsync();
if (result.Count != 1)
return Result.Failure<DoctorUser>(IdentityErrors.NotFound);
return result.First();
}
#endregion
#region Get receptionist user by user name full
public async Task<Result<ReceptionistUser>> GetReceptionistUserByUserNameFullAsync(string username)
{
var query
= _context.Set<ReceptionistUser>()
.Include(receptionistUser => receptionistUser.User)
.ThenInclude(user => user.Role)
.Where(receptionistUser => receptionistUser.User.UserName == username)
.Include(receptionistUser => receptionistUser.PersonalInfo);
var result = await query.ToListAsync();
if (result.Count != 1)
return Result.Failure<ReceptionistUser>(IdentityErrors.NotFound);
return result.First();
}
#endregion
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment