< Summary

Information
Class: Despesas.Application.Implementations.AcessoBusinessImpl<T1, T2>
Assembly: Despesas.Application
File(s): /src/Despesas.Application/Implementations/AcessoBusinessImpl.cs
Line coverage
52%
Covered lines: 65
Uncovered lines: 58
Coverable lines: 123
Total lines: 198
Line coverage: 52.8%
Branch coverage
31%
Covered branches: 19
Total branches: 60
Branch coverage: 31.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AuthenticationException(...)100%210%
AuthenticationSuccess(...)50%22100%
IsValidEmail(...)0%7280%
CheckIfUserIsTeste(...)50%2280%
.ctor(...)100%11100%
Create()100%11100%
ValidateCredentials()20.83%2112431.25%
ValidateExternalCredentials()0%110100%
ValidateCredentials()100%1212100%
RevokeToken(...)100%11100%
RecoveryPassword()0%620%
ChangePassword()100%11100%

File(s)

/src/Despesas.Application/Implementations/AcessoBusinessImpl.cs

#LineLine coverage
 1using AutoMapper;
 2using Despesas.Application.Abstractions;
 3using Despesas.Application.Authentication;
 4using Despesas.Application.Authentication.Abstractions;
 5using Despesas.Application.Dtos;
 6using Despesas.Application.Dtos.Abstractions;
 7using Despesas.Application.Dtos.Core;
 8using Despesas.GlobalException.CustomExceptions.Acesso;
 9using Despesas.GlobalException.CustomExceptions.Core;
 10using Despesas.Infrastructure.Email.Abstractions;
 11using Domain.Entities;
 12using EasyCryptoSalt;
 13using Microsoft.AspNetCore.Http;
 14using Repository.Persistency.Abstractions;
 15using System.IdentityModel.Tokens.Jwt;
 16using System.Security.Claims;
 17using System.Text.RegularExpressions;
 18using static Domain.Core.ValueObject.PerfilUsuario;
 19
 20namespace Despesas.Application.Implementations;
 21
 22public class AcessoBusinessImpl<DtoCa, DtoLogin> : IAcessoBusiness<DtoCa, DtoLogin> where DtoCa : AcessoDto where DtoLog
 23{
 24    private readonly ICrypto _crypto;
 25    private readonly IMapper _mapper;
 26    private readonly IAcessoRepositorioImpl _repositorio;
 27    private readonly IEmailSender _emailSender;
 28    private readonly ISigningConfigurations _singingConfiguration;
 29
 30    private AuthenticationDto AuthenticationException(string message, int statusCode = 400)
 031    {
 032        throw new CustomException(message, statusCode);
 33    }
 34
 35    private Task<AuthenticationDto> AuthenticationSuccess(Acesso acesso)
 136    {
 137        ClaimsIdentity identity = new ClaimsIdentity(new[]
 138        {
 139            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")),
 140            new Claim("role",  ((Perfil)acesso.Usuario.PerfilUsuario.Id).ToString()),
 141            new Claim(JwtRegisteredClaimNames.Sub, acesso.UsuarioId.ToString()),
 142            new Claim(JwtRegisteredClaimNames.AuthTime, acesso.RefreshTokenExpiry == null ? DateTimeOffset.UtcNow.ToUnix
 143            new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),
 144        });
 45
 146        DateTime createDate = DateTime.Now;
 147        DateTime expirationDate = createDate + TimeSpan.FromSeconds(_singingConfiguration.TokenConfiguration.Seconds);
 148        string token = _singingConfiguration.CreateAccessToken(identity);
 49
 150        var dto = new AuthenticationDto
 151        {
 152            Authenticated = true,
 153            Created = createDate.ToString("yyyy-MM-dd HH:mm:ss"),
 154            Expiration = expirationDate.ToString("yyyy-MM-dd HH:mm:ss"),
 155            AccessToken = token,
 156            RefreshToken = acesso.RefreshToken
 157        };
 58
 159        return Task.FromResult(dto);
 160    }
 61
 62    private static void IsValidEmail(string email)
 063    {
 064        if (string.IsNullOrEmpty(email) || string.IsNullOrWhiteSpace(email))
 065            throw new CampoObrigatorioException("Email não pode ser em branco ou nulo!");
 66
 067        if (email.Length > 256)
 068            throw new EmailInvalidoException();
 69
 070        string pattern = @"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$";
 071        Regex regex = new Regex(pattern);
 72
 073        if (!regex.IsMatch(email))
 074            throw new EmailInvalidoException();
 075    }
 76
 77    private void CheckIfUserIsTeste(Guid userIdentity)
 178    {
 179        var isUserTeste = _repositorio.Find(accout => accout.Login.Contains("teste@teste.com") && accout.UsuarioId == us
 180        if (isUserTeste is not null)
 081            throw new CampoObrigatorioException("Senha deste usuário não pode ser atualizada");
 182    }
 83
 1284    public AcessoBusinessImpl(IMapper mapper, IAcessoRepositorioImpl repositorio, SigningConfigurations singingConfigura
 1285    {
 1286        _mapper = mapper;
 1287        _repositorio = repositorio;
 1288        _singingConfiguration = singingConfiguration;
 1289        _emailSender = emailSender;
 1290        _crypto = crypto;
 1291    }
 92
 93    public async Task Create(DtoCa acessoDto)
 194    {
 195        var usuario = _mapper.Map<Usuario>(acessoDto);
 196        usuario = new Usuario().CreateUsuario(usuario);
 197        Acesso acesso = _mapper.Map<Acesso>(acessoDto);
 198        acesso.CreateAccount(usuario, _crypto.Encrypt(acessoDto.Senha));
 199        await _repositorio.Create(acesso);
 1100    }
 101
 102    public async Task<AuthenticationDto> ValidateCredentials(DtoLogin loginDto)
 4103    {
 4104        Acesso baseLogin = await _repositorio.Find(c => c.Login.Equals(loginDto.Email))
 4105            ?? throw new UsuarioInexistenteException();
 106
 1107        if (baseLogin?.Usuario?.StatusUsuario == StatusUsuario.Inativo)
 1108            throw new UsuarioInativoException();
 109
 0110        if (!_crypto.Verify(loginDto?.Senha ?? "", baseLogin?.Senha ?? ""))
 0111            throw new SenhaInvalidaException();
 112
 0113        bool credentialsValid = baseLogin is not null && loginDto?.Email == baseLogin.Login;
 0114        if (credentialsValid)
 0115        {
 0116            baseLogin.RefreshToken = _singingConfiguration.GenerateRefreshToken();
 0117            baseLogin.RefreshTokenExpiry = DateTime.UtcNow.AddDays(_singingConfiguration.TokenConfiguration.DaysToExpiry
 0118            await _repositorio.RefreshTokenInfo(baseLogin);
 0119            return await AuthenticationSuccess(baseLogin);
 120        }
 121
 0122        throw new CustomException("Usuário Inválido!", StatusCodes.Status401Unauthorized);
 0123    }
 124
 125    public async Task<AuthenticationDto> ValidateExternalCredentials(GoogleAuthenticationDto authenticationDto)
 0126    {
 0127        Acesso? baseLogin =  await _repositorio.Find(c => (c.ExternalProvider == authenticationDto.ExternalProvider
 0128        && c.ExternalId == authenticationDto.ExternalId)
 0129        && c.Login.Equals(authenticationDto.Email));
 130
 0131        if (baseLogin == null && !string.IsNullOrEmpty(authenticationDto.ExternalProvider))
 0132        {
 0133            var dtoCa = this._mapper.Map<DtoCa>(authenticationDto);
 0134            dtoCa.Senha = Guid.NewGuid().ToString("N");
 0135            await Create(dtoCa);
 136
 0137            baseLogin = await _repositorio.Find(c => c.Login.Equals(dtoCa.Email));
 0138        }
 139
 0140        bool credentialsValid = baseLogin is not null && authenticationDto.Email == baseLogin.Login;
 0141        if (credentialsValid && baseLogin is not null)
 0142        {
 0143            baseLogin.RefreshToken = _singingConfiguration.GenerateRefreshToken();
 0144            baseLogin.RefreshTokenExpiry = DateTime.UtcNow.AddDays(_singingConfiguration.TokenConfiguration.DaysToExpiry
 0145            await _repositorio.RefreshTokenInfo(baseLogin);
 0146            return await AuthenticationSuccess(baseLogin);
 147        }
 0148        return AuthenticationException("Usuário Inválido!");
 0149    }
 150
 151    public async Task<AuthenticationDto> ValidateCredentials(string refreshToken)
 4152    {
 4153        var baseLogin = await _repositorio.FindByRefreshToken(refreshToken);
 154
 4155        var credentialsValid = baseLogin is not null &&
 4156                               baseLogin.RefreshTokenExpiry >= DateTime.UtcNow &&
 4157                               refreshToken.Equals(baseLogin.RefreshToken) &&
 4158                               _singingConfiguration.ValidateRefreshToken(refreshToken);
 159
 4160        if (credentialsValid)
 1161            return await AuthenticationSuccess(baseLogin);
 3162        else if (baseLogin is not null)
 2163            await RevokeToken(baseLogin.Id);
 164
 3165        throw new RefreshTokenInvalidoException();
 1166    }
 167
 168    public Task RevokeToken(Guid idUsuario)
 2169    {
 2170        return _repositorio.RevokeRefreshToken(idUsuario);
 2171    }
 172
 173    public async Task RecoveryPassword(string email)
 0174    {
 0175        IsValidEmail(email);
 176
 0177        var acesso = await _repositorio.Find(account => account.Login.Equals(email))
 0178            ?? throw new UsuarioInexistenteException();
 0179        CheckIfUserIsTeste(acesso.Id);
 180
 0181        string newPassword = Guid.NewGuid().ToString("N").Substring(0, 8);
 182        try
 0183        {
 0184            await _repositorio.RecoveryPassword(email, newPassword);
 0185            _emailSender.SendEmailPassword(acesso.Usuario, newPassword);
 0186        }
 0187        catch
 0188        {
 0189            throw new EmailException();
 190        }
 0191    }
 192
 193    public async Task ChangePassword(Guid idUsuario, string password)
 1194    {
 1195        CheckIfUserIsTeste(idUsuario);
 1196        await _repositorio.ChangePassword(idUsuario, _crypto.Encrypt(password));
 1197    }
 198}