Skip to content

Commit

Permalink
!!!Feature: Confirmação de email pós cadastro adicionada.
Browse files Browse the repository at this point in the history
  • Loading branch information
LibardiFelipe committed Oct 9, 2022
1 parent 73ffb9e commit 7455db5
Show file tree
Hide file tree
Showing 28 changed files with 315 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public class RegisterUserCommand : Command
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string ProfilePictureUrl { get; set; }
public DateTime BirthDate { get; set; }

public override void Validate()
Expand Down
31 changes: 23 additions & 8 deletions TemplateBase.Application/Commands/Users/UserCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MediatR;
using System.Threading;
using System.Threading.Tasks;
using TemplateBase.Application.Commands.Auth;
using TemplateBase.Application.Commands.Base;
using TemplateBase.Application.Models;
using TemplateBase.Domain.Resources;
Expand All @@ -9,25 +10,39 @@
namespace TemplateBase.Application.Commands.Persons
{
public class UserCommandHandler : CommandHandler,
IRequestHandler<RegisterUserCommand, Result>
IRequestHandler<RegisterUserCommand, Result>,
IRequestHandler<VerifyUserCommand, Result>
{
private readonly IUserService _personService;
private readonly IUserService _userService;

public UserCommandHandler(IUserService personService)
public UserCommandHandler(IUserService userService)
{
_personService = personService;
_userService = userService;
}

public async Task<Result> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
{
if (request.IsInvalid())
return new Result(DefaultMessages.Handler_ComandoInvalido, false, request.Notifications);

var entity = await _personService.RegisterUserAsync(request.Name, request.Email,
request.Password, request.ProfilePictureUrl, request.BirthDate, cancellationToken);
var entity = await _userService.RegisterUserAsync(request.Name, request.Email,
request.Password, request.BirthDate, cancellationToken);

if (_personService.IsInvalid())
return new Result(DefaultMessages.Handler_FalhaAoExecutarComando, false, _personService.GetNotifications());
if (_userService.IsInvalid())
return new Result(DefaultMessages.Handler_FalhaAoExecutarComando, false, _userService.GetNotifications());

return new Result(DefaultMessages.Handler_ComandoExecutado, true, entity);
}

public async Task<Result> Handle(VerifyUserCommand request, CancellationToken cancellationToken)
{
if (request.IsInvalid())
return new Result(DefaultMessages.Handler_ComandoInvalido, false, request.Notifications);

var entity = await _userService.VerifyUserAsync(request.Hash, cancellationToken);

if (_userService.IsInvalid())
return new Result(DefaultMessages.Handler_FalhaAoExecutarComando, false, _userService.GetNotifications());

return new Result(DefaultMessages.Handler_ComandoExecutado, true, entity);
}
Expand Down
23 changes: 23 additions & 0 deletions TemplateBase.Application/Commands/Users/VerifyUserCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using TemplateBase.Application.Commands.Base;

namespace TemplateBase.Application.Commands.Auth
{
public class VerifyUserCommand : Command
{
public VerifyUserCommand()
{

}

public VerifyUserCommand(string hash)
{
Hash = hash;
}

public string Hash { get; set; }

public override void Validate()
{
}
}
}
10 changes: 5 additions & 5 deletions TemplateBase.Application/Queries/Users/UserQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class UserQuery : Query<User>
#region Membros privados
private string _name;
private string _email;
private EUserPermission? _permission = null;
private EUserType? _type = null;
private DateTime? _birthDate = null;
#endregion

Expand All @@ -34,9 +34,9 @@ public UserQuery FilterByEmail(string value)
return this;
}

public UserQuery FilterByPermission(EUserPermission? value)
public UserQuery FilterByType(EUserType? value)
{
_permission = value;
_type = value;
return this;
}

Expand All @@ -61,8 +61,8 @@ public override ISpecification<User> ToSpecification()
if (!string.IsNullOrWhiteSpace(_email))
spec.FilterByEmail(_email);

if (_permission.HasValue)
spec.FilterByPermission(_permission.Value);
if (_type.HasValue)
spec.FilterByType(_type.Value);

if (_birthDate.HasValue)
spec.FilterByBirthDate(_birthDate.Value);
Expand Down
2 changes: 1 addition & 1 deletion TemplateBase.Domain/Classes/AuthData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class AuthData
{
public string Name { get; set; }
public string Email { get; set; }
public EUserPermission Permission { get; set; }
public EUserType Type { get; set; }
public string Token { get; set; }
}
}
2 changes: 1 addition & 1 deletion TemplateBase.Domain/Classes/Email.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void InjectToBody(Dictionary<string, string> values)
return;

foreach (var item in values)
Body = Body.Replace("{" + item.Key + "}", item.Value);
Body = Body.Replace(item.Key, item.Value);
}

public void AddAddressee(string email)
Expand Down
57 changes: 49 additions & 8 deletions TemplateBase.Domain/Entities/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ public User(string name, string email, string password, string profilePictureUrl
ChangeProfilePictureUrl(profilePictureUrl, true);
ChangeBirthDate(birthDate, true);

// Por padrão, a permissão do usuário começa como somente leitura,
// e passa para Read/Write após confirmar o email.
ChangePermission(EUserPermission.Read, true);
// Verificação por email necessária
ChangeIsVerified(false, true);
// Usuário sempre começa sendo o básico
ChangeType(EUserType.Basic, true);
ChangeIsLocked(false, true);
}
#endregion

Expand All @@ -41,7 +43,10 @@ public User(string name, string email, string password, string profilePictureUrl
public string Password { get; private set; }
public string ProfilePictureUrl { get; private set; }
public DateTime BirthDate { get; private set; }
public EUserPermission Permission { get; private set; }
public EUserType Type { get; private set; }
public bool IsVerified { get; private set; }
public bool IsLocked { get; private set; }
public string LockReason { get; private set; }
#endregion

#region Validações
Expand All @@ -66,6 +71,42 @@ public User ChangeName(string value, bool fromConstructor = false)
return this;
}

public User ChangeIsVerified(bool value, bool fromConstructor = false)
{
if (!fromConstructor && IsVerified.Equals(value))
return this;

IsVerified = value;

FlagAsChanged();
return this;
}

public User ChangeIsLocked(bool value, bool fromConstructor = false)
{
if (!fromConstructor && IsLocked.Equals(value))
return this;

IsLocked = value;

FlagAsChanged();
return this;
}

public User ChangeLockReason(string value, bool fromConstructor = false)
{
if (!fromConstructor && (LockReason?.Equals(value) ?? false))
return this;

LockReason = value;
AddNotifications(new Contract<Notification>()
.Requires()
.IsNotNullOrWhiteSpace(LockReason, "LockReason", string.Format(DefaultMessages.CampoObrigatorio, "Motivo do Block")));

FlagAsChanged();
return this;
}

public User ChangeEmail(string value, bool fromConstructor = false)
{
if (!fromConstructor && (Email?.Equals(value) ?? false))
Expand Down Expand Up @@ -110,15 +151,15 @@ public User ChangeProfilePictureUrl(string value, bool fromConstructor = false)
return this;
}

public User ChangePermission(EUserPermission value, bool fromConstructor = false)
public User ChangeType(EUserType value, bool fromConstructor = false)
{
if (!fromConstructor && Permission.Equals(value))
if (!fromConstructor && Type.Equals(value))
return this;

Permission = value;
Type = value;
AddNotifications(new Contract<Notification>()
.Requires()
.IsNotNull(Permission, "Permission", string.Format(DefaultMessages.CampoObrigatorio, "Permissão")));
.IsNotNull(Type, "Type", string.Format(DefaultMessages.CampoObrigatorio, "Permissão")));

FlagAsChanged();
return this;
Expand Down
10 changes: 0 additions & 10 deletions TemplateBase.Domain/Enumerators/EUserPermission.cs

This file was deleted.

9 changes: 9 additions & 0 deletions TemplateBase.Domain/Enumerators/EUserType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TemplateBase.Domain.Enumerators
{
public enum EUserType : byte
{
Basic = 1,
VIP = 2,
Admin = 3
}
}
18 changes: 18 additions & 0 deletions TemplateBase.Domain/Resources/DefaultMessages.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions TemplateBase.Domain/Resources/DefaultMessages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
<data name="CampoObrigatorio" xml:space="preserve">
<value>O campo de {0} é obrigatório.</value>
</data>
<data name="ConfirmacaoEmailPendente" xml:space="preserve">
<value>É necessário confirmar o seu email antes de se contectar.</value>
</data>
<data name="EmailJaExistente" xml:space="preserve">
<value>O email informado já se encontra cadastrado.</value>
</data>
Expand Down Expand Up @@ -153,4 +156,7 @@
<data name="Service_InternalError" xml:space="preserve">
<value>Um erro interno ocorreu durante a execução do serviço!</value>
</data>
<data name="UsuarioBloqueado" xml:space="preserve">
<value>Sua conta foi bloqueada pelo seguinte motivo: {0}</value>
</data>
</root>
18 changes: 15 additions & 3 deletions TemplateBase.Domain/Services/AuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,25 @@ public async Task<AuthData> AuthenticateAsync(string email, string password, Can
return null;
}

if (user.IsVerified is false)
{
AddNotification("User", DefaultMessages.ConfirmacaoEmailPendente);
return null;
}

if (user.IsLocked)
{
AddNotification("User", string.Format(DefaultMessages.UsuarioBloqueado, user.LockReason));
return null;
}

return new AuthData
{
Name = user.Name,
Email = user.Email,
Permission = user.Permission,
Type = user.Type,
Token = GenerateToken(user)
};
};
}

private string GenerateToken(User user)
Expand All @@ -59,7 +71,7 @@ private string GenerateToken(User user)
Subject = new ClaimsIdentity(new[]
{
new Claim("Id", user.Id.ToString()),
new Claim(ClaimTypes.Role, user.Permission.ToString()),
new Claim(ClaimTypes.Role, user.Type.ToString()),
}),
Expires = DateTime.UtcNow.AddHours(2),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
Expand Down
3 changes: 2 additions & 1 deletion TemplateBase.Domain/Services/Contracts/IUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace TemplateBase.Domain.Services.Contracts
{
public interface IUserService : IService
{
Task<User> RegisterUserAsync(string name, string email, string password, string profilePicture, DateTime birthDate, CancellationToken cancellationToken);
Task<User> RegisterUserAsync(string name, string email, string password, DateTime birthDate, CancellationToken cancellationToken);
Task<bool> VerifyUserAsync(string hash, CancellationToken cancellationToken);
}
}
Loading

0 comments on commit 7455db5

Please sign in to comment.