feat: add simple check for username and password

This commit is contained in:
Stevan Freeborn
2026-02-01 06:12:49 -06:00
parent a1d22b0ec2
commit 093ee2c357
2 changed files with 135 additions and 14 deletions
+24 -2
View File
@@ -11,8 +11,30 @@ internal static class Endpoint
private static async Task<IResult> HandleAsync([FromBody] LoginRequest loginRequest) private static async Task<IResult> HandleAsync([FromBody] LoginRequest loginRequest)
{ {
Console.WriteLine(loginRequest.Username); const string ADMIN_USERNAME = "Stevan";
Console.WriteLine(loginRequest.Password); const string ADMIN_PASSWORD = "@Password1";
// TODO: Implement actual auth flow
// 1. We want to make sure that
// the user exists
// 2. We want to make sure that
// tha the password is correct
// 3. We want to issue an access token
// with a refresh token
// 4. We want to store the refresh
// token
// 5. We want to set the refresh
// token in a cookie
// TODO: Things we need
// 1. We need a user model
// 2. We need a refresh token model
if (loginRequest.Username is not ADMIN_USERNAME || loginRequest.Password is not ADMIN_PASSWORD)
{
return Results.Unauthorized();
}
return Results.Ok(); return Results.Ok();
} }
} }
@@ -1,28 +1,127 @@
using System.Net.Http.Json;
using Microsoft.AspNetCore.Mvc;
namespace FiscalOS.API.Tests.Integration; namespace FiscalOS.API.Tests.Integration;
public class LoginTests(TestApi testApi) : IClassFixture<TestApi> public class LoginTests(TestApi testApi) : IClassFixture<TestApi>
{ {
private readonly TestApi _testApi = testApi; private readonly TestApi _testApi = testApi;
[Fact] [Theory]
public async Task Login_WhenUserSubmitsWithoutUsernameOrPassword_ItShouldReturn400WithProblemDetails() [ClassData<LoginValidationTestCases>]
public async Task Login_WhenUserSubmitsInvalidRequest_ItShouldReturn400WithProblemDetails(LoginValidationTestCase tc)
{ {
var client = _testApi.CreateClient(); var client = _testApi.CreateClient();
var res = await client.PostAsJsonAsync("/login", new { }, TestContext.Current.CancellationToken); var req = new
{
username = tc.Username,
password = tc.Password,
};
res.StatusCode.Should().Be(System.Net.HttpStatusCode.BadRequest); var res = await client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken);
res.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problem = await res.Content.ReadFromJsonAsync<ValidationProblemDetails>(TestContext.Current.CancellationToken); var problem = await res.Content.ReadFromJsonAsync<ValidationProblemDetails>(TestContext.Current.CancellationToken);
problem!.Errors.Should().BeEquivalentTo(new Dictionary<string, string[]>() problem!.Errors.Should().BeEquivalentTo(tc.ExpectedErrors);
}
[Fact]
public async Task Login_WhenUserCredentialsAreIncorrect_ItShouldReturn401WithProblemDetails()
{
var client = _testApi.CreateClient();
var req = new
{ {
["Username"] = ["The Username field is required."], username = "Test",
["Password"] = ["The Password field is required."] password = "@Password2",
}); };
var res = await client.PostAsJsonAsync("/login", req, TestContext.Current.CancellationToken);
res.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
}
public class LoginValidationTestCases : TheoryData<LoginValidationTestCase>
{
public LoginValidationTestCases()
{
Add(new LoginValidationTestCase(
"No username or password",
string.Empty,
string.Empty,
new Dictionary<string, string[]>()
{
["Username"] = ["The Username field is required."],
["Password"] = ["The Password field is required."]
}
));
Add(new LoginValidationTestCase(
"No username",
string.Empty,
"@Password1",
new Dictionary<string, string[]>()
{
["Username"] = ["The Username field is required."],
}
));
Add(new LoginValidationTestCase(
"No password",
"Stevan",
string.Empty,
new Dictionary<string, string[]>()
{
["Password"] = ["The Password field is required."]
}
));
}
}
public record LoginValidationTestCase : IXunitSerializable
{
public string Name { get; private set; } = string.Empty;
public string Username { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public Dictionary<string, string[]> ExpectedErrors { get; private set; } = [];
public override string ToString()
{
return Name;
}
public LoginValidationTestCase()
{
}
public LoginValidationTestCase(
string name,
string username,
string password,
Dictionary<string, string[]> expectedErrors
)
{
Name = name;
Username = username;
Password = password;
ExpectedErrors = expectedErrors;
}
public void Deserialize(IXunitSerializationInfo info)
{
Name = info.GetValue<string>(nameof(Name)) ?? string.Empty;
Username = info.GetValue<string>(nameof(Username)) ?? string.Empty;
Password = info.GetValue<string>(nameof(Password)) ?? string.Empty;
ExpectedErrors = info.GetValue<Dictionary<string, string[]>>(nameof(ExpectedErrors)) ?? [];
}
public void Serialize(IXunitSerializationInfo info)
{
info.AddValue(nameof(Name), Name);
info.AddValue(nameof(Username), Username);
info.AddValue(nameof(Password), Password);
info.AddValue(nameof(ExpectedErrors), ExpectedErrors);
} }
} }