Files
step3/api/QuestionsApi.Tests/AuthTests.cs
T

92 lines
3.5 KiB
C#

using Microsoft.Extensions.Configuration;
using QuestionsApi.Models;
using QuestionsApi.Services;
using System.IdentityModel.Tokens.Jwt;
using Xunit;
namespace QuestionsApi.Tests;
public sealed class AuthTests
{
[Theory]
[InlineData("valid_user", "[email protected]", "password1", null)]
[InlineData("ab", "[email protected]", "password1", "Username")]
[InlineData("invalid-user", "[email protected]", "password1", "Username")]
[InlineData("valid_user", "not-an-email", "password1", "email")]
[InlineData("valid_user", "[email protected]", "short", "Password")]
public void NewAccountValidationRejectsInvalidInput(
string username, string email, string password, string? expectedError)
{
var result = AuthValidation.ValidateNewAccount(username, email, password);
if (expectedError is null) Assert.Null(result);
else Assert.Contains(expectedError, result!, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void PasswordResetCodesAreSixDigitsAndBoundToTheirRequest()
{
var service = new PasswordResetCodeService(Configuration(new Dictionary<string, string?>
{
["PasswordReset:HmacKey"] = "A-test-only-key-that-is-longer-than-thirty-two-bytes"
}));
var code = service.GenerateCode();
var hash = service.Hash("request-one", code);
Assert.Matches("^[0-9]{6}$", code);
Assert.True(service.Verify("request-one", code, hash));
Assert.False(service.Verify("request-two", code, hash));
Assert.False(service.Verify("request-one", "000000", hash));
}
[Fact]
public void PasswordResetCanRemainUnconfiguredWithoutBreakingAuthentication()
{
var service = new PasswordResetCodeService(Configuration([]));
Assert.False(service.IsConfigured);
}
[Fact]
public void JwtContainsCompatibleIdentityRoleAndAuthVersionClaims()
{
var service = new JwtTokenService(Configuration(new Dictionary<string, string?>
{
["Jwt:Key"] = "A-test-only-jwt-key-that-is-longer-than-thirty-two-bytes",
["Jwt:Issuer"] = "promiscuity",
["Jwt:Audience"] = "promiscuity-auth-api"
}));
var user = new AuthUser
{
Id = "507f1f77bcf86cd799439011",
Username = "doctor",
Role = "SUPER",
AuthVersion = 4
};
var generated = service.Generate(user);
var token = new JwtSecurityTokenHandler().ReadJwtToken(generated.Token);
Assert.Equal("promiscuity", token.Issuer);
Assert.Contains("promiscuity-auth-api", token.Audiences);
Assert.Equal("4", token.Claims.Single(claim => claim.Type == "auth_ver").Value);
Assert.Equal(generated.Jti, token.Id);
}
[Fact]
public void LegacyUsersDefaultToAuthVersionZero()
{
Assert.Equal(0, new AuthUser().AuthVersion);
}
[Fact]
public void SteamClaimedIdExtractionRejectsUnexpectedHostsAndLengths()
{
Assert.Equal("76561198000000000",
SteamOpenIdService.ExtractSteamId("https://steamcommunity.com/openid/id/76561198000000000"));
Assert.Null(SteamOpenIdService.ExtractSteamId("https://example.com/openid/id/76561198000000000"));
Assert.Null(SteamOpenIdService.ExtractSteamId("https://steamcommunity.com/openid/id/123"));
}
private static IConfiguration Configuration(Dictionary<string, string?> values) =>
new ConfigurationBuilder().AddInMemoryCollection(values).Build();
}