Skip to content

Commit

Permalink
Add Database Auto Migration (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
vanderlan authored Oct 21, 2023
1 parent 2c78631 commit 774ff16
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/Orion.Api/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public static void ConfigureServices(this IServiceCollection services, IConfigur

services.ConfigureSwagger();

services.AddDatabaseContext();
services.AddUnitOfWork();
services.AddDomainServices();

services.ConfigureAutoMapper();
Expand Down
21 changes: 21 additions & 0 deletions src/Orion.Api/Configuration/MigrationsConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.EntityFrameworkCore;
using Orion.Data.Context;

namespace Orion.Api.Configuration;

public static class MigrationsConfiguration
{
public static WebApplication RunMigrations(this WebApplication app)
{
using var scope = app.Services.CreateScope();

var dataContext = scope.ServiceProvider.GetRequiredService<DataContext>();

if (dataContext.Database.GetPendingMigrations().Any())
{
dataContext.Database.Migrate();
}

return app;
}
}
2 changes: 1 addition & 1 deletion src/Orion.Api/Controllers/V1/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async Task<IActionResult> Login([FromBody] UserLoginModel model)
[HttpPost]
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenModel refreshTokenModel)
{
var userOutput = Mapper.Map<UserOutput>(await _userService.GetUserByRefreshTokenAsync(refreshTokenModel.RefreshToken, refreshTokenModel.Token));
var userOutput = Mapper.Map<UserOutput>(await _userService.SignInWithRehreshTokenAsync(refreshTokenModel.RefreshToken, refreshTokenModel.Token));

return await AuthorizeUser(userOutput);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Orion.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@

app.ConfigureApp();

app.RunMigrations();

app.Run();
6 changes: 3 additions & 3 deletions src/Orion.Data/Context/DataContext.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Orion.Data.Mapping;
using Orion.Domain.Entities;
using System;
using System.Linq;
using System.Threading.Tasks;
using Orion.Data.Mapping;
using Microsoft.Extensions.Configuration;
using Orion.Domain.Entities;

namespace Orion.Data.Context;

Expand Down
2 changes: 1 addition & 1 deletion src/Orion.Domain/Services/Interfaces/IUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ public interface IUserService : IBaseService<User>
{
Task<User> LoginAsync(string email, string password);
Task<RefreshToken> AddRefreshTokenAsync(RefreshToken refreshToken);
Task<User> GetUserByRefreshTokenAsync(string refreshToken, string expiredToken);
Task<User> SignInWithRehreshTokenAsync(string refreshToken, string expiredToken);
Task<PagedList<User>> ListPaginateAsync(BaseFilter<User> filter);
}
16 changes: 8 additions & 8 deletions src/Orion.Domain/Services/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,18 @@ public async Task UpdateAsync(User user)

public async Task<RefreshToken> AddRefreshTokenAsync(RefreshToken refreshToken)
{
var existantRefresToken = await _unitOfWork.RefreshTokenRepository.SearchByAsync(x => x.Email == refreshToken.Email);
var existantRefreshToken = await _unitOfWork.RefreshTokenRepository.SearchByAsync(x => x.Email == refreshToken.Email);

if (existantRefresToken.Any())
return existantRefresToken.First();
if (existantRefreshToken.Any())
return existantRefreshToken.First();

var added = await _unitOfWork.RefreshTokenRepository.AddAsync(refreshToken);
await _unitOfWork.CommitAsync();

return added;
}

public async Task<User> GetUserByRefreshTokenAsync(string refreshToken, string expiredToken)
public async Task<User> SignInWithRehreshTokenAsync(string refreshToken, string expiredToken)
{
if (string.IsNullOrEmpty(refreshToken))
{
Expand All @@ -107,15 +107,15 @@ public async Task<User> GetUserByRefreshTokenAsync(string refreshToken, string e

var email = GetClaimFromJtwToken(expiredToken, JwtRegisteredClaimNames.Email);

var refreshTokens = (await _unitOfWork.RefreshTokenRepository.SearchByAsync(x => x.Refreshtoken.Equals(refreshToken) && x.Email == email)).ToList();
var userRefreshToken = (await _unitOfWork.RefreshTokenRepository.SearchByAsync(x => x.Refreshtoken.Equals(refreshToken) && x.Email == email)).FirstOrDefault();

if (refreshTokens != null && refreshTokens.Any())
if (userRefreshToken is not null)
{
var user = (await _unitOfWork.UserRepository.SearchByAsync(x => x.Email == refreshTokens.First().Email)).FirstOrDefault();
var user = (await _unitOfWork.UserRepository.SearchByAsync(x => x.Email == userRefreshToken.Email)).FirstOrDefault();

if (user is not null)
{
await _unitOfWork.RefreshTokenRepository.DeleteAsync(refreshTokens.First().PublicId);
await _unitOfWork.RefreshTokenRepository.DeleteAsync(userRefreshToken.PublicId);
await _unitOfWork.CommitAsync();

return user;
Expand Down
15 changes: 11 additions & 4 deletions src/Orion.Ioc/Dependencies/DependenciesInjectionConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@
using Orion.Domain.Services.Interfaces;
using Orion.Domain.Repositories.UnitOfWork;
using Orion.Domain.Services;
using Orion.Data.Context;

namespace Orion.Ioc.Dependencies;

public static class DependenciesInjectionConfiguration
{
public static void AddDomainServices(this IServiceCollection services)
{
//Unit of Work
services.AddTransient<IUnitOfWork, UnitOfWork>();

//Domain Services
services.AddScoped<ICustomerService, CustomerService>();
services.AddScoped<IUserService, UserService>();
}

public static void AddDatabaseContext(this IServiceCollection services)
{
services.AddScoped<DataContext>();
}

public static void AddUnitOfWork(this IServiceCollection services)
{
services.AddTransient<IUnitOfWork, UnitOfWork>();
}
}
2 changes: 1 addition & 1 deletion tests/Orion.Test/Api/Controllers/AuthControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private void SetupServiceMock()
.ReturnsAsync(_validUser);

userServiceMock.Setup(x => x.AddRefreshTokenAsync(It.IsAny<RefreshToken>())).ReturnsAsync(RefreshTokenFaker.Get());
userServiceMock.Setup(x => x.GetUserByRefreshTokenAsync(_validRefreshToken.Refreshtoken, It.IsAny<string>())).ReturnsAsync(_validUser);
userServiceMock.Setup(x => x.SignInWithRehreshTokenAsync(_validRefreshToken.Refreshtoken, It.IsAny<string>())).ReturnsAsync(_validUser);

var inMemorySettings = new Dictionary<string, string> {
{"JwtOptions:SymmetricSecurityKey", "5cCI6IkpXVCJ9.eyJlbWFpbCI6InZhbmRlcmxhbi5nc0BnbWFpbC5jb20iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJhZG1p"},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Orion.Data.UnitOfWork;
using Orion.Domain.Repositories.UnitOfWork;
using Orion.Ioc.Dependencies;
Expand All @@ -16,8 +15,6 @@ public DependencyInjectionSetupFixture()

serviceCollection.AddDomainServices();

serviceCollection.RemoveAll<IUnitOfWork>();

serviceCollection.AddTransient<IUnitOfWork>(s => new UnitOfWork(TestBootstrapper.GetInMemoryDbContextOptions()));
serviceCollection.AddLogging();
serviceCollection.AddLocalization(options => options.ResourcesPath = @"Resources");
Expand Down
4 changes: 2 additions & 2 deletions tests/Orion.Test/Domain/Services/UserServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public async Task RefreshTokenAddAync_WithValidEmail_AddARefreskToken()
var refreshTokenAdded = await userService.AddRefreshTokenAsync(new RefreshToken { Email = userAdded.Email, Refreshtoken = refreshToken });

//act
var userByRefreshToken = await userService.GetUserByRefreshTokenAsync(refreshTokenAdded.Refreshtoken, Token);
var userByRefreshToken = await userService.SignInWithRehreshTokenAsync(refreshTokenAdded.Refreshtoken, Token);

//assert
Assert.NotNull(userByRefreshToken);
Expand Down Expand Up @@ -259,7 +259,7 @@ public async Task GetUserByRefreshTokenAsync_WithInvalidId_ThrowsUnauthorizedUse
await userService.AddRefreshTokenAsync(new RefreshToken { Email = userAdded.Email, Refreshtoken = Guid.NewGuid().ToString() });

//act
var exeption = await Assert.ThrowsAsync<UnauthorizedUserException>(() => userService.GetUserByRefreshTokenAsync(refreshToken, token));
var exeption = await Assert.ThrowsAsync<UnauthorizedUserException>(() => userService.SignInWithRehreshTokenAsync(refreshToken, token));

//assert
Assert.Equal(exeption.Message, messages[UserMessages.InvalidRefreshToken]);
Expand Down

0 comments on commit 774ff16

Please sign in to comment.