summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Controllers/LoginController.cs41
-rw-r--r--Pages/Component/Titlebar.razor115
-rw-r--r--Pages/Gallery.razor1
-rw-r--r--Pages/TagDefinitions.razor1
-rw-r--r--Pages/Upload.razor1
-rw-r--r--Pages/ViewMedia.razor2
-rw-r--r--Program.cs4
-rw-r--r--Properties/launchSettings.json1
-rw-r--r--Services/GlobalUserService.cs7
-rw-r--r--Services/UserService.cs48
10 files changed, 117 insertions, 104 deletions
diff --git a/Controllers/LoginController.cs b/Controllers/LoginController.cs
new file mode 100644
index 0000000..fff3e6e
--- /dev/null
+++ b/Controllers/LoginController.cs
@@ -0,0 +1,41 @@
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Mvc;
+using System.Security.Claims;
+
+namespace HyperBooru.Controllers;
+
+[ApiController]
+[Route("/")]
+public class LoginController : Controller {
+ private IHttpContextAccessor httpContextAccessor;
+ public LoginController(IHttpContextAccessor httpContextAccessor) =>
+ this.httpContextAccessor = httpContextAccessor;
+
+ [HttpPost("Login")]
+ public async Task<IActionResult> Login(
+ [FromForm] string username,
+ [FromForm] string password) {
+
+ var claims = new Claim[] {
+ new Claim(ClaimTypes.NameIdentifier, username)
+ };
+
+ var claimsIdentity = new ClaimsIdentity(
+ claims,
+ CookieAuthenticationDefaults.AuthenticationScheme);
+
+ var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
+
+ if(username == "admin" && password == "test") {
+ await httpContextAccessor.HttpContext!.SignInAsync(claimsPrincipal);
+ return Ok();
+ } else {
+ return StatusCode(403);
+ }
+ }
+
+ [HttpPost("Logout")]
+ public async Task Logout() =>
+ await httpContextAccessor.HttpContext!.SignOutAsync();
+}
diff --git a/Pages/Component/Titlebar.razor b/Pages/Component/Titlebar.razor
index 71f3bd0..bcd5f61 100644
--- a/Pages/Component/Titlebar.razor
+++ b/Pages/Component/Titlebar.razor
@@ -1,64 +1,83 @@
@inject IUserService userService
@inject NavigationManager navigationManager
@inject IJSRuntime jsRuntime
+@inject AuthenticationStateProvider authStateProvider
-@if(authorized) {
- <div id="navbar">
- <a href="/">Home</a>
- <a href="/TagDefinitions">Tags</a>
- <a href="/Gallery?ingest=true">Ingest</a>
- <a href="/Upload">Upload</a>
- <a href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a>
+<script suppress-error="BL9992">
+ async function login() {
+ var username = document.querySelector('input#username');
+ var password = document.querySelector('input#password');
- <p id="nsfw-label">NSFW</p>
- <div id="nsfw-switch">
- <NsfwSwitch/>
- </div>
- <form action="/Gallery" method="get">
- <input type="text" name="q" placeholder="Search"/>
- </form>
- <a href="javascript:;" @onclick=userService.Logout>Logout</a>
- </div>
- <AboutDialog @ref=aboutDialog/>
-} else {
- <div id="navbar">
- <h2>Login</h2>
- <form @onsubmit=Login class="login">
- <input @bind=username name="username" placeholder="Username" type="text"/>
- <input @bind=password name="password" placeholder="Password" type="password"/>
- </form>
- <a href="javascript:;" @onclick=Login>Login</a>
- <a href="javascript:;" @onclick=userService.Logout>Logout</a>
- </div>
- <script suppress-error="BL9992">
- function warnBadLogin() {
+ var formData = new FormData();
+ formData.append('username', username.value);
+ formData.append('password', password.value);
+
+ var resp = await fetch('/Login', {
+ method: 'POST',
+ body: formData
+ });
+
+ if(resp.ok) {
+ if(document.referrer) {
+ window.location.href = document.referrer;
+ } else {
+ window.location.href = '/';
+ }
+ } else if(resp.status == 403) {
var form = document.querySelector('form.login');
form.classList.remove('bad-login');
@* TODO: improve this hacky method of triggering reflow *@
form.offsetWidth;
form.classList.add('bad-login');
- document.querySelector('form.login input').focus();
+ username.value = password.value = null;
+ username.focus();
+ } else {
+ alert('Unknown error while attempting to login!');
}
- </script>
-}
-
-@code {
- private bool authorized = false;
+ }
- private string username;
- private string password;
+ async function logout() {
+ var resp = await fetch('/Logout', { method: 'POST' });
+ if(resp.ok) {
+ window.location.href = '/Login';
+ } else {
+ alert('Error logging out!');
+ }
+ }
+</script>
- private AboutDialog aboutDialog;
+<AuthorizeView>
+ <Authorized>
+ <div id="navbar">
+ <a href="/">Home</a>
+ <a href="/TagDefinitions">Tags</a>
+ <a href="/Gallery?ingest=true">Ingest</a>
+ <a href="/Upload">Upload</a>
+ <a href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a>
- private void Login() {
- if(userService.Login(username, password))
- navigationManager.NavigateTo("/");
- else
- WarnBadLogin();
- }
+ <p id="nsfw-label">NSFW</p>
+ <div id="nsfw-switch">
+ <NsfwSwitch/>
+ </div>
+ <form action="/Gallery" method="get">
+ <input type="text" name="q" placeholder="Search"/>
+ </form>
+ <a href="javascript:logout();">Logout</a>
+ </div>
+ <AboutDialog @ref=aboutDialog/>
+ </Authorized>
+ <NotAuthorized>
+ <div id="navbar">
+ <h2>Login</h2>
+ <form onsubmit="login" class="login">
+ <input id="username" placeholder="Username" type="text"/>
+ <input id="password" placeholder="Password" type="password"/>
+ </form>
+ <a href="javascript:login();">Login</a>
+ </div>
+ </NotAuthorized>
+</AuthorizeView>
- private void WarnBadLogin() {
- jsRuntime.InvokeVoidAsync("warnBadLogin");
- username = password = "";
- }
+@code {
+ private AboutDialog aboutDialog;
}
diff --git a/Pages/Gallery.razor b/Pages/Gallery.razor
index 7e183f2..d473c28 100644
--- a/Pages/Gallery.razor
+++ b/Pages/Gallery.razor
@@ -6,6 +6,7 @@
@inject IUserService userService
@inject IJSRuntime jsRuntime
@implements IDisposable
+@attribute [Authorize]
<PageTitle>@Title</PageTitle>
diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor
index 1a29b40..f728631 100644
--- a/Pages/TagDefinitions.razor
+++ b/Pages/TagDefinitions.razor
@@ -3,6 +3,7 @@
@inject ITagService tagService
@inject IUserService userService
@implements IDisposable
+@attribute [Authorize]
<PageTitle>Tag Definitions</PageTitle>
diff --git a/Pages/Upload.razor b/Pages/Upload.razor
index 7f7980b..614cec0 100644
--- a/Pages/Upload.razor
+++ b/Pages/Upload.razor
@@ -1,4 +1,5 @@
@page "/Upload"
+@attribute [Authorize]
<div id="dropzone">
<p>Drag a file to upload it<br/>or click to select one or more file(s)</p>
diff --git a/Pages/ViewMedia.razor b/Pages/ViewMedia.razor
index 1b6f959..444fbc5 100644
--- a/Pages/ViewMedia.razor
+++ b/Pages/ViewMedia.razor
@@ -4,7 +4,7 @@
@inject IDbContextFactory<HBContext> dbFactory
@inject ITagService tagService
@inject IMediaService mediaService
-@*@attribute [Authorize]*@
+@attribute [Authorize]
<PageTitle>@title</PageTitle>
diff --git a/Program.cs b/Program.cs
index d8aa5c6..cda77d3 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using System.Text.Json.Serialization;
using HyperBooru.Services;
+using Microsoft.AspNetCore.Authentication.Cookies;
namespace HyperBooru;
@@ -9,6 +10,8 @@ public class Program {
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication().AddCookie();
builder.Services.AddHttpContextAccessor();
+ builder.Services.AddAuthentication(
+ CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
builder.Services.AddControllers().AddJsonOptions(o => {
var converter = new JsonStringEnumConverter();
o.JsonSerializerOptions.Converters.Add(converter);
@@ -22,7 +25,6 @@ public class Program {
builder.Services.AddScoped<ISearchService, SearchService>();
builder.Services.AddScoped<ITagService, TagService>();
builder.Services.AddScoped<IMediaService, MediaService>();
- builder.Services.AddSingleton<IGlobalUserService, GlobalUserService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddHostedService<OcrService>();
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
index 9f4966c..b1659dc 100644
--- a/Properties/launchSettings.json
+++ b/Properties/launchSettings.json
@@ -13,6 +13,7 @@
"HyperBooru": {
"commandName": "Project",
"launchBrowser": true,
+ "launchUrl": "Login",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
diff --git a/Services/GlobalUserService.cs b/Services/GlobalUserService.cs
deleted file mode 100644
index adafce2..0000000
--- a/Services/GlobalUserService.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace HyperBooru.Services;
-
-public interface IGlobalUserService {
-}
-
-public class GlobalUserService : IGlobalUserService {
-}
diff --git a/Services/UserService.cs b/Services/UserService.cs
index 96f5b5f..d2abea3 100644
--- a/Services/UserService.cs
+++ b/Services/UserService.cs
@@ -1,18 +1,9 @@
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authentication.Cookies;
-using System.Runtime.InteropServices;
-using System.Security.Claims;
-using System.Security.Principal;
-
-namespace HyperBooru.Services;
+namespace HyperBooru.Services;
public interface IUserService {
public bool ShowNsfw { get; set; }
public event EventHandler<bool> ShowNsfwChanged;
-
- public bool Login(string username, string password);
- public void Logout();
}
public class UserService : IUserService {
@@ -27,41 +18,4 @@ public class UserService : IUserService {
public event EventHandler<bool> ShowNsfwChanged;
private bool showNsfw = false;
-
- private IGlobalUserService globalUserService;
- private IHttpContextAccessor httpContextAccessor;
-
- public UserService(
- IGlobalUserService globalUserService,
- IHttpContextAccessor httpContextAccessor) {
-
- this.globalUserService = globalUserService;
- this.httpContextAccessor = httpContextAccessor;
- }
-
- public bool Login(string username, string password) {
- var claims = new Claim[] {
- };
-
- var claimsIdentity = new ClaimsIdentity(
- claims,
- CookieAuthenticationDefaults.AuthenticationScheme);
-
- var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
-
- if(httpContextAccessor.HttpContext is null)
- return false;
-
- httpContextAccessor.HttpContext.SignInAsync(claimsPrincipal)
- .GetAwaiter()
- .GetResult();
-
- return true;
- }
-
- public void Logout() {
- httpContextAccessor.HttpContext?.SignOutAsync()
- .GetAwaiter()
- .GetResult();
- }
}