diff --git a/OliverBooth.sln b/OliverBooth.sln index cb5bf3b..c17858e 100644 --- a/OliverBooth.sln +++ b/OliverBooth.sln @@ -21,6 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scss", "scss", "{822F528E-3 src\scss\prism.vs.scss = src\scss\prism.vs.scss src\scss\prism.css = src\scss\prism.css src\scss\ribbon.scss = src\scss\ribbon.scss + src\scss\admin.scss = src\scss\admin.scss EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ts", "ts", "{BB9F76AC-292A-4F47-809D-8BBBA6E0A048}" diff --git a/OliverBooth/Controllers/Blog/AdminController.cs b/OliverBooth/Controllers/AdminController.cs similarity index 83% rename from OliverBooth/Controllers/Blog/AdminController.cs rename to OliverBooth/Controllers/AdminController.cs index 27b7757..6fa83c3 100644 --- a/OliverBooth/Controllers/Blog/AdminController.cs +++ b/OliverBooth/Controllers/AdminController.cs @@ -1,17 +1,17 @@ using System.Net; using Microsoft.AspNetCore.Mvc; -using OliverBooth.Data.Blog; +using OliverBooth.Data.Web; using OliverBooth.Services; using ISession = OliverBooth.Data.Blog.ISession; -namespace OliverBooth.Controllers.Blog; +namespace OliverBooth.Controllers; [Controller] [Route("auth/admin")] public sealed class AdminController : ControllerBase { private readonly ILogger _logger; - private readonly IBlogUserService _userService; + private readonly IUserService _userService; private readonly ISessionService _sessionService; /// @@ -21,7 +21,7 @@ public sealed class AdminController : ControllerBase /// The user service. /// The session service. public AdminController(ILogger logger, - IBlogUserService userService, + IUserService userService, ISessionService sessionService) { _logger = logger; @@ -39,14 +39,14 @@ public sealed class AdminController : ControllerBase if (string.IsNullOrWhiteSpace(loginEmail)) { _logger.LogInformation("Login attempt from {Host} with empty login", remoteIpAddress); - return RedirectToPage("/blog/admin/login"); + return RedirectToPage("/admin/login"); } if (string.IsNullOrWhiteSpace(loginPassword)) { _logger.LogInformation("Login attempt as '{Email}' from {Host} with empty password", loginEmail, remoteIpAddress); - return RedirectToPage("/blog/admin/login"); + return RedirectToPage("/admin/login"); } if (_userService.VerifyLogin(loginEmail, loginPassword, out IUser? user)) @@ -56,14 +56,14 @@ public sealed class AdminController : ControllerBase else { _logger.LogInformation("Login attempt for '{Email}' failed from {Host}", loginEmail, remoteIpAddress); - return RedirectToPage("/blog/admin/login"); + return RedirectToPage("/admin/login"); } ISession session = _sessionService.CreateSession(Request, user); Span sessionBytes = stackalloc byte[16]; session.Id.TryWriteBytes(sessionBytes); Response.Cookies.Append("sid", Convert.ToBase64String(sessionBytes)); - return RedirectToPage("/blog/admin/index"); + return RedirectToPage("/admin/index"); } [HttpGet("logout")] @@ -72,7 +72,6 @@ public sealed class AdminController : ControllerBase if (_sessionService.TryGetSession(Request, out ISession? session, true)) _sessionService.DeleteSession(session); - Response.Cookies.Delete("sid"); - return RedirectToPage("/blog/admin/login"); + return _sessionService.DeleteSessionCookie(Response); } } diff --git a/OliverBooth/Pages/Admin/Index.cshtml b/OliverBooth/Pages/Admin/Index.cshtml new file mode 100644 index 0000000..128ae22 --- /dev/null +++ b/OliverBooth/Pages/Admin/Index.cshtml @@ -0,0 +1,8 @@ +@page +@model OliverBooth.Pages.Admin.Index + +@{ + ViewData["Title"] = "Admin"; +} + +

Hello @Model.CurrentUser.DisplayName!

\ No newline at end of file diff --git a/OliverBooth/Pages/Admin/Index.cshtml.cs b/OliverBooth/Pages/Admin/Index.cshtml.cs new file mode 100644 index 0000000..e2be20a --- /dev/null +++ b/OliverBooth/Pages/Admin/Index.cshtml.cs @@ -0,0 +1,41 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using OliverBooth.Data.Web; +using OliverBooth.Services; +using ISession = OliverBooth.Data.Blog.ISession; + +namespace OliverBooth.Pages.Admin; + +public class Index : PageModel +{ + private readonly ILogger _logger; + private readonly IUserService _userService; + private readonly ISessionService _sessionService; + + public Index(ILogger logger, IUserService userService, ISessionService sessionService) + { + _logger = logger; + _userService = userService; + _sessionService = sessionService; + } + + public IUser CurrentUser { get; private set; } = null!; + + public IActionResult OnGet() + { + if (!_sessionService.TryGetSession(HttpContext.Request, out ISession? session)) + { + _logger.LogDebug("Session not found; redirecting"); + return _sessionService.DeleteSessionCookie(Response); + } + + if (!_userService.TryGetUser(session.UserId, out IUser? user)) + { + _logger.LogDebug("User not found; redirecting"); + return _sessionService.DeleteSessionCookie(Response); + } + + CurrentUser = user; + return Page(); + } +} diff --git a/OliverBooth/Pages/Admin/Login.cshtml b/OliverBooth/Pages/Admin/Login.cshtml new file mode 100644 index 0000000..267dd40 --- /dev/null +++ b/OliverBooth/Pages/Admin/Login.cshtml @@ -0,0 +1,30 @@ +@page +@model OliverBooth.Pages.Admin.Login + +@{ + ViewData["Title"] = "Login"; +} + +@section Styles +{ + +} + + \ No newline at end of file diff --git a/OliverBooth/Pages/Admin/Login.cshtml.cs b/OliverBooth/Pages/Admin/Login.cshtml.cs new file mode 100644 index 0000000..b4a6bfc --- /dev/null +++ b/OliverBooth/Pages/Admin/Login.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace OliverBooth.Pages.Admin; + +public class Login : PageModel +{ + public void OnGet() + { + + } +} diff --git a/OliverBooth/Program.cs b/OliverBooth/Program.cs index e772130..7d2e7d0 100644 --- a/OliverBooth/Program.cs +++ b/OliverBooth/Program.cs @@ -7,6 +7,7 @@ using OliverBooth.Markdown.Template; using OliverBooth.Markdown.Timestamp; using OliverBooth.Services; using Serilog; +using X10D.Hosting.DependencyInjection; Log.Logger = new LoggerConfiguration() .WriteTo.Console() @@ -36,11 +37,11 @@ builder.Services.AddHttpClient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddHostedSingleton(); builder.Services.AddRazorPages().AddRazorRuntimeCompilation(); builder.Services.AddControllersWithViews(); builder.Services.AddRouting(options => options.LowercaseUrls = true); diff --git a/src/scss/admin.scss b/src/scss/admin.scss new file mode 100644 index 0000000..9f0b2bb --- /dev/null +++ b/src/scss/admin.scss @@ -0,0 +1,4 @@ +.form-signin { + max-width: 330px; + padding: 1rem; +} \ No newline at end of file