| @@ -2,7 +2,7 @@ | |||
| { | |||
| public interface IUserService | |||
| { | |||
| Task<AuthenticateResponseDto?> Authenticate(AuthenticateRequestDto model); | |||
| Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(AuthenticateRequestDto model); | |||
| Task<IEnumerable<User?>> GetAll(); | |||
| @@ -28,23 +28,56 @@ namespace Diligent.WebAPI.Business.Services | |||
| await _userManager.CreateAsync(user, model.Password); | |||
| } | |||
| public async Task<AuthenticateResponseDto?> Authenticate(AuthenticateRequestDto model) | |||
| public async Task<ServiceResponseDTO<AuthenticateResponseDto>> Authenticate(AuthenticateRequestDto model) | |||
| { | |||
| var user = await _userManager.FindByNameAsync(model.Username); | |||
| // return null if user not found | |||
| if (user == null) | |||
| return null; | |||
| if (user == null) | |||
| { | |||
| return new ServiceResponseDTO<AuthenticateResponseDto> | |||
| { | |||
| IsError = true, | |||
| ErrorMessage = "Username is not valid" | |||
| }; | |||
| } | |||
| var isLocked = await _userManager.IsLockedOutAsync(user); | |||
| if (isLocked) | |||
| return new ServiceResponseDTO<AuthenticateResponseDto> | |||
| { | |||
| IsError = true, | |||
| ErrorMessage = "The account is locked out" | |||
| }; | |||
| var result = await _userManager.CheckPasswordAsync(user, model.Password); | |||
| // password is not correct | |||
| if (!result) | |||
| return null; | |||
| { | |||
| await _userManager.AccessFailedAsync(user); | |||
| isLocked = await _userManager.IsLockedOutAsync(user); | |||
| if(isLocked) | |||
| return new ServiceResponseDTO<AuthenticateResponseDto> | |||
| { | |||
| IsError = true, | |||
| ErrorMessage = "The account is locked out" | |||
| }; | |||
| return new ServiceResponseDTO<AuthenticateResponseDto> | |||
| { | |||
| IsError = true, | |||
| ErrorMessage = "Password is not correct" | |||
| }; | |||
| } | |||
| // authentication successful so generate jwt token | |||
| var token = GenerateJwtToken(user); | |||
| return new AuthenticateResponseDto | |||
| var data = new AuthenticateResponseDto | |||
| { | |||
| Id = user.Id, | |||
| Username = user.UserName, | |||
| @@ -52,6 +85,11 @@ namespace Diligent.WebAPI.Business.Services | |||
| LastName = user.LastName, | |||
| Token = token | |||
| }; | |||
| return new ServiceResponseDTO<AuthenticateResponseDto> | |||
| { | |||
| Data = data | |||
| }; | |||
| } | |||
| private string GenerateJwtToken(User user) | |||
| @@ -10,6 +10,7 @@ global using Diligent.WebAPI.Contracts.DTOs.Insurer; | |||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookDefinition; | |||
| global using Diligent.WebAPI.Contracts.DTOs.WebhookSubscription; | |||
| global using Diligent.WebAPI.Contracts.DTOs.Auth; | |||
| global using Diligent.WebAPI.Contracts.DTOs; | |||
| global using Diligent.WebAPI.Contracts.Exceptions; | |||
| global using Microsoft.EntityFrameworkCore; | |||
| @@ -0,0 +1,15 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace Diligent.WebAPI.Contracts.DTOs | |||
| { | |||
| public class ServiceResponseDTO<T> where T : class | |||
| { | |||
| public bool IsError { get; set; } = false; | |||
| public string ErrorMessage { get; set; } | |||
| public T Data { get; set; } | |||
| } | |||
| } | |||
| @@ -32,10 +32,10 @@ | |||
| { | |||
| var response = await _userService.Authenticate(model); | |||
| if (response == null) | |||
| return BadRequest(new { message = "Username or password is incorrect" }); | |||
| if (response.IsError is true) | |||
| return BadRequest(new { message = response.ErrorMessage }); | |||
| return Ok(response); | |||
| return Ok(response.Data); | |||
| } | |||
| } | |||
| } | |||
| @@ -7,10 +7,14 @@ namespace Diligent.WebAPI.Host.Extensions | |||
| { | |||
| IServiceCollection services = builder.Services; | |||
| services.AddIdentity<User, AppRole>() | |||
| .AddRoles<AppRole>() | |||
| .AddEntityFrameworkStores<DatabaseContext>() | |||
| .AddDefaultTokenProviders(); | |||
| services.AddIdentity<User, AppRole>(opt => | |||
| { | |||
| opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); | |||
| opt.Lockout.MaxFailedAccessAttempts = 5; | |||
| }) | |||
| .AddRoles<AppRole>() | |||
| .AddEntityFrameworkStores<DatabaseContext>() | |||
| .AddDefaultTokenProviders(); | |||
| } | |||
| } | |||
| } | |||