- Updated AddInfrastructure method to accept an environment name parameter for conditional Redis caching configuration. - Implemented logic to skip Redis caching setup in the Testing environment. - Added InMemoryCacheService for testing purposes, providing a mock implementation of ICacheService. - Enhanced TransactionBehavior to skip transactions for InMemory databases. - Updated functional tests to remove Redis-related services and ensure proper database setup for testing.
164 lines
6.8 KiB
C#
164 lines
6.8 KiB
C#
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using IamService.Domain.AggregatesModel.UserAggregate;
|
|
using IamService.Domain.AggregatesModel.RoleAggregate;
|
|
using IamService.Domain.SeedWork;
|
|
using IamService.Infrastructure.Repositories;
|
|
|
|
namespace IamService.Infrastructure;
|
|
|
|
/// <summary>
|
|
/// EN: Dependency injection extensions for Infrastructure layer.
|
|
/// VI: Dependency injection extensions cho Infrastructure layer.
|
|
/// </summary>
|
|
public static class DependencyInjection
|
|
{
|
|
/// <summary>
|
|
/// EN: Add Infrastructure services to DI container.
|
|
/// VI: Thêm Infrastructure services vào DI container.
|
|
/// </summary>
|
|
public static IServiceCollection AddInfrastructure(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
string? environmentName = null)
|
|
{
|
|
// EN: Get database connection string
|
|
// VI: Lấy database connection string
|
|
var connectionString = configuration.GetConnectionString("DefaultConnection")
|
|
?? configuration["DATABASE_URL"]
|
|
?? throw new InvalidOperationException("Database connection string not configured");
|
|
|
|
// EN: Add DbContext with PostgreSQL
|
|
// VI: Thêm DbContext với PostgreSQL
|
|
services.AddDbContext<IamServiceContext>(options =>
|
|
{
|
|
options.UseNpgsql(connectionString, npgsqlOptions =>
|
|
{
|
|
npgsqlOptions.MigrationsAssembly(typeof(IamServiceContext).Assembly.FullName);
|
|
npgsqlOptions.EnableRetryOnFailure(
|
|
maxRetryCount: 3,
|
|
maxRetryDelay: TimeSpan.FromSeconds(10),
|
|
errorCodesToAdd: null);
|
|
});
|
|
|
|
// EN: Use OpenIddict EF Core stores
|
|
// VI: Sử dụng OpenIddict EF Core stores
|
|
options.UseOpenIddict();
|
|
});
|
|
|
|
// EN: Add ASP.NET Core Identity
|
|
// VI: Thêm ASP.NET Core Identity
|
|
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
|
|
{
|
|
// EN: Password settings
|
|
// VI: Cài đặt mật khẩu
|
|
options.Password.RequireDigit = true;
|
|
options.Password.RequireLowercase = true;
|
|
options.Password.RequireUppercase = true;
|
|
options.Password.RequireNonAlphanumeric = true;
|
|
options.Password.RequiredLength = 8;
|
|
|
|
// EN: Lockout settings
|
|
// VI: Cài đặt khóa tài khoản
|
|
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
|
|
options.Lockout.MaxFailedAccessAttempts = 5;
|
|
options.Lockout.AllowedForNewUsers = true;
|
|
|
|
// EN: User settings
|
|
// VI: Cài đặt user
|
|
options.User.RequireUniqueEmail = true;
|
|
options.SignIn.RequireConfirmedEmail = false;
|
|
})
|
|
.AddEntityFrameworkStores<IamServiceContext>()
|
|
.AddDefaultTokenProviders();
|
|
|
|
// EN: Configure OpenIddict
|
|
// VI: Cấu hình OpenIddict
|
|
services.AddOpenIddict()
|
|
// EN: Register the OpenIddict core components
|
|
// VI: Đăng ký OpenIddict core components
|
|
.AddCore(options =>
|
|
{
|
|
options.UseEntityFrameworkCore()
|
|
.UseDbContext<IamServiceContext>();
|
|
})
|
|
// EN: Register the OpenIddict server components
|
|
// VI: Đăng ký OpenIddict server components
|
|
.AddServer(options =>
|
|
{
|
|
// EN: Enable token endpoints
|
|
// VI: Bật token endpoints
|
|
options.SetTokenEndpointUris("/connect/token")
|
|
.SetUserinfoEndpointUris("/connect/userinfo")
|
|
.SetIntrospectionEndpointUris("/connect/introspect")
|
|
.SetRevocationEndpointUris("/connect/revoke");
|
|
|
|
// EN: Enable flows
|
|
// VI: Bật flows
|
|
options.AllowPasswordFlow()
|
|
.AllowRefreshTokenFlow()
|
|
.AllowClientCredentialsFlow();
|
|
|
|
// EN: Register scopes
|
|
// VI: Đăng ký scopes
|
|
options.RegisterScopes("openid", "profile", "email", "roles", "api", "offline_access");
|
|
|
|
// EN: Token lifetimes
|
|
// VI: Thời hạn token
|
|
options.SetAccessTokenLifetime(TimeSpan.FromMinutes(15))
|
|
.SetRefreshTokenLifetime(TimeSpan.FromDays(7));
|
|
|
|
// EN: Development settings
|
|
// VI: Cài đặt development
|
|
options.AddDevelopmentEncryptionCertificate()
|
|
.AddDevelopmentSigningCertificate()
|
|
.DisableAccessTokenEncryption(); // EN: Disable encryption for dev / VI: Tắt mã hóa cho dev
|
|
|
|
// EN: Accept anonymous clients (for password flow without client_id)
|
|
// VI: Chấp nhận anonymous clients (cho password flow không cần client_id)
|
|
options.AcceptAnonymousClients();
|
|
|
|
// EN: Configure ASP.NET Core integration
|
|
// VI: Cấu hình tích hợp ASP.NET Core
|
|
options.UseAspNetCore()
|
|
.EnableTokenEndpointPassthrough()
|
|
.EnableUserinfoEndpointPassthrough()
|
|
.DisableTransportSecurityRequirement(); // EN: Allow HTTP for dev / VI: Cho phép HTTP cho dev
|
|
})
|
|
// EN: Register the OpenIddict validation components
|
|
// VI: Đăng ký OpenIddict validation components
|
|
.AddValidation(options =>
|
|
{
|
|
options.UseLocalServer();
|
|
options.UseAspNetCore();
|
|
});
|
|
|
|
// EN: Register repositories
|
|
// VI: Đăng ký repositories
|
|
services.AddScoped<IUserRepository, UserRepository>();
|
|
services.AddScoped<IRoleRepository, RoleRepository>();
|
|
services.AddScoped<IUnitOfWork>(sp => sp.GetRequiredService<IamServiceContext>());
|
|
|
|
// EN: Configure Redis caching (skip in Testing environment)
|
|
// VI: Cấu hình Redis caching (bỏ qua trong Testing environment)
|
|
if (!string.Equals(environmentName, "Testing", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var redisSettings = new Caching.RedisSettings();
|
|
configuration.GetSection(Caching.RedisSettings.SectionName).Bind(redisSettings);
|
|
|
|
services.AddSingleton<StackExchange.Redis.IConnectionMultiplexer>(sp =>
|
|
{
|
|
var connectionString = redisSettings.GetConnectionString();
|
|
return StackExchange.Redis.ConnectionMultiplexer.Connect(connectionString);
|
|
});
|
|
|
|
services.AddSingleton<Caching.ICacheService, Caching.RedisCacheService>();
|
|
}
|
|
|
|
return services;
|
|
}
|
|
}
|
|
|