using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Azaion.Common; using Azaion.Common.Configs; using Azaion.Common.Database; using Azaion.Common.Entities; using Azaion.Common.Requests; using Azaion.Services; using FluentValidation; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddEnvironmentVariables(); var jwtConfig = builder.Configuration.GetSection(nameof(JwtConfig)).Get(); if (jwtConfig == null) throw new Exception("Missing configuration section: JwtConfig"); var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.Secret)); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(o => { o.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtConfig.Issuer, ValidAudience = jwtConfig.Audience, IssuerSigningKey = signingKey }; }); builder.Services.AddAuthorization(); builder.Services.AddHttpContextAccessor(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.Configure(builder.Configuration.GetSection(nameof(ResourcesConfig))); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(sp => new DbFactory(sp.GetService>()!.Value.AzaionDb)); builder.Services.AddValidatorsFromAssemblyContaining(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapPost("/login", async (string username, string password, IUserService userService, CancellationToken cancellationToken) => { var user = await userService.ValidateUser(username, password); var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity([ new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Name, user.Email), new Claim(ClaimTypes.Role, user.Role.ToString()), new Claim(Constants.HARDWARE_ID, user.HardwareId) ]), Expires = DateTime.UtcNow.AddHours(2), Issuer = jwtConfig.Issuer, Audience = jwtConfig.Audience, SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); return Results.Ok(new { Token = tokenString }); }); app.MapPost("/register-user", async (RegisterUserRequest registerUserRequest, IUserService userService, CancellationToken cancellationToken) => await userService.RegisterUser(registerUserRequest, cancellationToken)) .RequireAuthorization(p => p.RequireRole(RoleEnum.ApiAdmin.ToString())); app.MapPost("/resources", async (UploadResourceRequest uploadResourceRequest, IResourcesService resourceService, CancellationToken cancellationToken) => await resourceService.SaveResource(uploadResourceRequest, cancellationToken)) .RequireAuthorization(p => p.RequireRole(RoleEnum.ApiAdmin.ToString())); app.MapPost("/resources/get", async (GetResourceRequest request, IUserService userService, IResourcesService resourcesService, CancellationToken cancellationToken) => { var user = userService.CurrentUser; if (user == null) throw new BusinessException(ExceptionEnum.NoUser, "No current user"); if (string.IsNullOrEmpty(user.HardwareId)) await userService.UpdateHardwareId(user.Email, request.HardwareId); var ms = new MemoryStream(); var key = Security.MakeEncryptionKey(user.Email, request.Password); await resourcesService.GetEncryptedResource(request.ResourceEnum, key, ms, cancellationToken); return ms; }).RequireAuthorization(); app.Run();