using System.Net; using System.Net.Mail; using System.Reflection; using System.Text; using GamificationService.Database; using GamificationService.Database.Repositories; using GamificationService.Logs; using GamificationService.Mapper; using GamificationService.Services.Cookies; using GamificationService.Services.CurrentUsers; using GamificationService.Services.InstructionTests; using GamificationService.Services.JWT; using GamificationService.Services.NotificationService; using GamificationService.Services.Rights; using GamificationService.Services.Roles; using GamificationService.Services.UsersProfile; using GamificationService.Utils; using GamificationService.Utils.Factory; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Serilog; namespace GamificationService.Extensions; public static class MappingExtensions { public static IServiceCollection AddMapping(this IServiceCollection services) { services.AddAutoMapper(typeof(MappingProfile)); return services; } } public static class CachingExtensions { public static IServiceCollection AddRedisCaching(this IServiceCollection services, IConfiguration configuration) { services.AddStackExchangeRedisCache(options => { options.Configuration = configuration["Redis:ConnectionString"] ?? "localhost:6379"; options.InstanceName = configuration["Redis:InstanceName"] ?? "default"; }); return services; } } public static class LoggingExtensions { public static IHostBuilder UseCustomSerilog(this IHostBuilder hostBuilder) { LoggingConfigurator.ConfigureLogging(); return hostBuilder.UseSerilog(); } } public static class DatabaseExtensions { public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration) { services.AddDbContext(x => { var dbSettings = configuration.GetSection("DatabaseSettings"); var hostname = dbSettings["Hostname"] ?? "localhost"; var port = dbSettings["Port"] ?? "5432"; var name = dbSettings["Name"] ?? "postgres"; var username = dbSettings["Username"] ?? "postgres"; var password = dbSettings["Password"] ?? "postgres"; x.UseNpgsql($"Server={hostname}:{port};Database={name};Uid={username};Pwd={password};"); }); services.AddScoped(sp => new UnitOfWork(sp.GetRequiredService())); services.AddScoped(typeof(GenericRepository<>)); return services; } } public static class SwaggerExtensions { public static IServiceCollection AddSwagger(this IServiceCollection services) { string projectName = Assembly.GetExecutingAssembly().GetName().Name; services.AddOpenApi(); services.AddEndpointsApiExplorer(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = projectName, Version = "v1" }); // Set the comments path for the Swagger JSON and UI var xmlFile = $"{projectName}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); return services; } } public static class JwtAuthExtensions { public static IServiceCollection AddJwtAuth(this IServiceCollection services, IConfiguration configuration) { var jwtSettings = configuration.GetSection("JwtSettings"); var secretKey = jwtSettings["SecretKey"] ?? throw new SystemException("JwtSettings:SecretKey not found"); var key = Encoding.ASCII.GetBytes(secretKey); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; }); return services; } } public static class BackendServicesExtensions { public static IServiceCollection AddBackendServices(this IServiceCollection services) { services.AddScoped(); services.AddScoped(); return services; } } public static class UtilServicesExtensions { public static IServiceCollection AddUtilServices(this IServiceCollection services) { services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); return services; } } public static class NotificationSettings { public static IServiceCollection AddPushNotifications(this IServiceCollection services, IConfiguration configuration) { var notificationSettings = configuration.GetSection("NotificationSettings"); var apiKey = notificationSettings["ApiKey"]; var token = notificationSettings["Token"]; var baseUrl = notificationSettings["Url"]; var projectId = notificationSettings["ProjectId"]; HttpClient client = new HttpClient(); client.BaseAddress = new Uri(baseUrl); client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}"); services.AddSingleton(provider => { var logger = provider.GetRequiredService>(); return new PushNotificationsClient(client, logger, token, projectId); }); return services; } } public static class EmailExtensions { public static IServiceCollection AddEmail(this IServiceCollection services, IConfiguration configuration) { var smtpSettings = configuration.GetSection("EmailSettings"); var host = smtpSettings["Host"] ?? "localhost"; var port = Convert.ToInt32(smtpSettings["Port"] ?? "25"); var username = smtpSettings["Username"] ?? "username"; var password = smtpSettings["Password"] ?? "password"; var email = smtpSettings["EmailFrom"] ?? "email"; services.AddScoped(sp => new SmtpClient(host) { Port = port, Credentials = new NetworkCredential(username, password), EnableSsl = true, }); services.AddSingleton(); return services; } } public static class FactoryExtensions { public static IServiceCollection AddFactories(this IServiceCollection services) { services.AddSingleton(); services.AddSingleton(); return services; } }