using VPNAuth.Server; using VPNAuth.Server.Database; using VPNAuth.Server.Responses; Config.CreateIfNotExists(); var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(new StaticFileOptions { RequestPath = "/static" }); app.UseRouting(); app.MapGet("/accept-auth/{id}", async (HttpContext context, int id) => { using var db = new Database(); var authRequest = db.AuthRequests.Find(id); if (authRequest == null || authRequest.Accepted) { context.Response.StatusCode = StatusCodes.Status404NotFound; return; } authRequest.Accepted = true; db.SaveChanges(); var config = Config.Read(); context.Response.StatusCode = StatusCodes.Status302Found; context.Response.Headers["Location"] = config.FindApp(authRequest.ClientId)!.RedirectUri! + "?code=" + authRequest.Code + "&state=" + authRequest.State; }); app.MapPost("/access-token", async (HttpContext context) => { var config = Config.Read(); if (context.Request.Form["grant_type"] != "authorization_code") { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } var clientSecret = config.FindApp(context.Request.Form["client_id"]!)!.Secret; // FIXME: null pointer if (clientSecret != null && clientSecret != context.Request.Form["client_secret"]) { context.Response.StatusCode = StatusCodes.Status403Forbidden; return; } using var db = new Database(); var authRequest = db.AuthRequests .Where(request => request.Code == context.Request.Form["code"].ToString()) .ToList() .FirstOrDefault(); if (authRequest == null) { context.Response.StatusCode = StatusCodes.Status404NotFound; return; } // TODO: validate code verifier -> context.Request.Form["code_verifier"] var accessTokenEntry = db.AccessTokens.Add(new AccessToken { ClientId = authRequest.ClientId, Scopes = authRequest.Scopes, CreationTime = DateTime.Now, Token = PkceUtils.GenerateToken() }); db.SaveChanges(); await context.Response.WriteAsJsonAsync(new Token { AccessToken = accessTokenEntry.Entity.Token, TokenType = "Bearer", Expires = 0 // TODO: change to actual value }); }); app.MapPost("/user-info", async (HttpContext context) => { using var db = new Database(); ConfigUser? configUser = context.GetUser(); if (configUser == null) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; } UserInformation? userInformation = db.UserInformation.Where(user => user.Sub == configUser!.Username) .ToList().FirstOrDefault() ?? db.Add(new UserInformation { Sub = configUser!.Username }).Entity; if (context.Request.Form.ContainsKey("given-name")) userInformation.GivenName = context.Request.Form["given-name"]!; if (context.Request.Form.ContainsKey("family-name")) userInformation.FamilyName = context.Request.Form["family-name"]!; if (context.Request.Form.ContainsKey("preferred-username")) userInformation.PreferredUsername = context.Request.Form["preferred-username"]!; if (context.Request.Form.ContainsKey("email")) userInformation.Email = context.Request.Form["email"]!; if (context.Request.Form.ContainsKey("picture")) userInformation.Picture = context.Request.Form["picture"]!; userInformation.Name = userInformation.GivenName + " " + userInformation.FamilyName; db.SaveChanges(); }); app.MapStaticAssets(); app.MapRazorPages() .WithStaticAssets(); app.Run("http://localhost:8080");