Skip to content

Commit

Permalink
User as aggregate root (#26)
Browse files Browse the repository at this point in the history
* feat!: user as aggregate

* fix: registration logic

* fix: tests
  • Loading branch information
QimbE committed Jan 14, 2024
1 parent c7911f6 commit 36b763f
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 50 deletions.
8 changes: 0 additions & 8 deletions Application/Authentication/Register/RegisterCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@ public async Task<Result<bool>> Handle(RegisterCommand request, CancellationToke
var user = User.Create(request.Name, request.Email, hash, Role.DefaultUser);

_context.Users.Add(user);

// refreshToken
var refreshToken = RefreshToken.Create("sample", user.Id);

// Security reasons
refreshToken.MakeExpire();

_context.RefreshTokens.Add(refreshToken);

await _context.SaveChangesAsync(cancellationToken);

Expand Down
2 changes: 1 addition & 1 deletion Domain/Users/RefreshToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static RefreshToken Create(string value, Guid userId)
{
return new(
value,
DateTime.UtcNow.AddDays(LifeTime),
DateTime.UtcNow,
userId
);
}
Expand Down
9 changes: 8 additions & 1 deletion Domain/Users/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ protected User(string name, string email, string password, int roleId, bool isVe
IsVerified = isVerified;
}

public static User Create(string name, string email, string password, int roleId)
public static User Create(
string name,
string email,
string password,
int roleId
)
{
User result = new(name, email, password, roleId, false);

result.RefreshToken = RefreshToken.Create("sample", result.Id);

result.RaiseEvent(new UserCreatedDomainEvent(result.Id));

Expand Down
3 changes: 2 additions & 1 deletion Infrastructure/Configurations/UserConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public void Configure(EntityTypeBuilder<User> builder)
builder
.HasOne(u => u.RefreshToken)
.WithOne(r => r.Owner)
.HasForeignKey<RefreshToken>(r => r.Id);
.HasForeignKey<RefreshToken>(r => r.Id)
.IsRequired();

// Many-to-one with role
builder
Expand Down
19 changes: 5 additions & 14 deletions Tests/ApplicationTests/Authentication/LogoutCommandHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,10 @@ public static IEnumerable<object[]> InvalidUsersAndTokens()
{
var user1 = User.Create("123", "test", "123123", 1);

// Expired token
var expiredToken = RefreshToken.Create("123123", user1.Id);
expiredToken.MakeExpire();

// Token that does not exist
var nonExistentToken = RefreshToken.Create("123", Guid.NewGuid());

return [[user1, expiredToken], [user1, nonExistentToken]];
return [[user1, user1.RefreshToken], [user1, nonExistentToken]];
}

[Theory]
Expand All @@ -35,11 +31,6 @@ public void Logout_ShouldReturnException_OnInvalidToken(User user, RefreshToken
// Arrange
RecreateDbContext();
Context.Users.Add(user);

if (token.Id == user.Id)
{
Context.RefreshTokens.Add(token);
}

Context.SaveChangesAsync().GetAwaiter().GetResult();

Expand Down Expand Up @@ -68,17 +59,17 @@ public void Refresh_ShouldReturnTokenResponse_OnValidToken()
RecreateDbContext();

var user = User.Create("123", "test", "123123", 1);

var token = RefreshToken.Create("123123123123", user.Id);

user.RefreshToken.Update("123123123");
user.VerifyEmail();

Context.Users.Add(user);
Context.RefreshTokens.Add(token);

Context.SaveChangesAsync().GetAwaiter().GetResult();

var handler = new LogoutCommandHandler(Context);

var request = new LogoutCommand(token.Value);
var request = new LogoutCommand(user.RefreshToken.Value);

// Act
var res = handler.Handle(request, default).GetAwaiter().GetResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ public static IEnumerable<object[]> InvalidUsersAndTokens()
{
var user1 = User.Create("123", "test", "123123", 1);

// Expired token
var expiredToken = RefreshToken.Create("123123", user1.Id);
expiredToken.MakeExpire();

// Token that does not exist
var nonExistentToken = RefreshToken.Create("123", Guid.NewGuid());

return [[user1, expiredToken], [user1, nonExistentToken]];
return [[user1, user1.RefreshToken], [user1, nonExistentToken]];
}

[Theory]
Expand Down Expand Up @@ -67,17 +63,17 @@ public void Refresh_ShouldReturnTokenResponse_OnValidToken()
RecreateDbContext();

var user = User.Create("123", "test", "123123", 1);

var token = RefreshToken.Create("123123123123", user.Id);

user.VerifyEmail();

user.RefreshToken.Update(JwtProvider.GenerateRefreshToken());
Context.Users.Add(user);
Context.RefreshTokens.Add(token);

Context.SaveChangesAsync().GetAwaiter().GetResult();

var handler = new RefreshCommandHandler(Context, JwtProvider);

var request = new RefreshCommand(token.Value);
var request = new RefreshCommand(user.RefreshToken.Value);

// Act
var res = handler.Handle(request, default).GetAwaiter().GetResult();
Expand Down
1 change: 1 addition & 0 deletions Tests/DomainTests/RefreshTokenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void MakeExpire_Should_MakeTokenExpire()
{
// Arrange
var token = RefreshToken.Create("random123", Guid.NewGuid());
token.Update("bimbimbambam");

// Act
token.MakeExpire();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ public async Task Logout_Should_ReturnBadRequest_IfRefreshTokenIsInvalid()
var httpClient = Factory.CreateClient();

var fakeToken = "bimbimbimbambambam";
var actualToken = "hehehehuh";

var user = User.Create("bimbim", "bambam", "123123", Role.DefaultUser);

var token = RefreshToken.Create(actualToken, user.Id);

httpClient.DefaultRequestHeaders.Add("cookie", [$"refreshToken={fakeToken}"]);

Expand All @@ -48,7 +45,6 @@ public async Task Logout_Should_ReturnBadRequest_IfRefreshTokenIsInvalid()
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

context.Users.Add(user);
context.RefreshTokens.Add(token);

await context.SaveChangesAsync();

Expand All @@ -72,7 +68,8 @@ public async Task Logout_Should_ReturnBaseResponse_IfRefreshTokenValid()

var user = User.Create("bimbim", "bambam", "123123", Role.DefaultUser);

var token = RefreshToken.Create(actualToken, user.Id);
user.RefreshToken.Update(actualToken);
user.VerifyEmail();

httpClient.DefaultRequestHeaders.Add("cookie", [$"refreshToken={actualToken}"]);

Expand All @@ -81,11 +78,9 @@ public async Task Logout_Should_ReturnBaseResponse_IfRefreshTokenValid()
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

context.Users.Add(user);
context.RefreshTokens.Add(token);

await context.SaveChangesAsync();


// Act
var response = await httpClient.PutAsync("Authentication/Logout", null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ public async Task Refresh_Should_ReturnBadRequest_IfRefreshTokenIsInvalid()
var httpClient = Factory.CreateClient();

var fakeToken = "bimbimbimbambambam";
var actualToken = "hehehehuh";

var user = User.Create("bimbim", "bambam", "123123", Role.DefaultUser);

var token = RefreshToken.Create(actualToken, user.Id);

httpClient.DefaultRequestHeaders.Add("cookie", [$"refreshToken={fakeToken}"]);

Expand All @@ -49,7 +46,6 @@ public async Task Refresh_Should_ReturnBadRequest_IfRefreshTokenIsInvalid()
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

context.Users.Add(user);
context.RefreshTokens.Add(token);

await context.SaveChangesAsync();

Expand All @@ -69,11 +65,12 @@ public async Task Refresh_Should_ReturnTokenResponse_IfRefreshTokenValid()
// Arrange
var httpClient = Factory.CreateClient();

var actualToken = "hehehehuh";

var user = User.Create("bimbim", "bambam", "123123", Role.DefaultUser);

var token = RefreshToken.Create(actualToken, user.Id);
user.RefreshToken.Update("123123123");
user.VerifyEmail();

var actualToken = user.RefreshToken.Value;

httpClient.DefaultRequestHeaders.Add("cookie", [$"refreshToken={actualToken}"]);

Expand All @@ -82,11 +79,9 @@ public async Task Refresh_Should_ReturnTokenResponse_IfRefreshTokenValid()
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

context.Users.Add(user);
context.RefreshTokens.Add(token);

await context.SaveChangesAsync();


// Act
var response = await httpClient.PutAsync("Authentication/Refresh", null);

Expand Down

0 comments on commit 36b763f

Please sign in to comment.