mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 19:23:15 +00:00
* fix: bump nanoid to 3.3.16 and postcss to 8.5.26 Bump nanoid from 3.3.16 to 3.3.18 in web/ Bump postcss from 8.5.25 to 8.5.26 in web/ Closes [Dependabot 47] (https://github.com/Sea-Haven-Industries/proposal-system/security/dependabot/47) * fix(api): sanitize request path in internal API key logs (SEC-29) Strip CR/LF from Request.Path before logging invalid-key and disallowed-path warnings so CodeQL alerts 4 and 5 close without changing 401/403 behavior. * fix(api): log user id instead of email on cognito role sync (SEC-29) Keep AuthResponse.Email unchanged so CodeQL alert 1 closes without altering the callback payload. * fix(api): use sanitized path on both internal key logs (SEC-29) The 401 branch referenced an out-of-scope identifier and the 403 branch skipped SanitizeForLog. Cover newline-in-path logs and Cognito role-sync user-id logging with tests.
85 lines
2.8 KiB
C#
85 lines
2.8 KiB
C#
using FluentAssertions;
|
|
using Microsoft.Extensions.Configuration;
|
|
using NSubstitute;
|
|
using ProposalSystem.Api.Controllers;
|
|
using ProposalSystem.Domain.Entities;
|
|
using ProposalSystem.Tests.Helpers;
|
|
using Xunit;
|
|
|
|
namespace ProposalSystem.Tests.Controllers;
|
|
|
|
public class AuthControllerRoleSyncTests
|
|
{
|
|
[Fact(DisplayName = "SEC-29: Cognito role sync logs user id, not email")]
|
|
public async Task RoleChange_LogsUserIdNotEmail()
|
|
{
|
|
var email = "pii@example.com";
|
|
var user = new User
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
CognitoSub = "sub-role-sync",
|
|
Email = email,
|
|
DisplayName = "Test User",
|
|
Role = UserRole.Dispatcher,
|
|
IsActive = true,
|
|
CreatedAt = DateTime.UtcNow,
|
|
UpdatedAt = DateTime.UtcNow,
|
|
};
|
|
|
|
var (controller, db, logger) = CreateController(user);
|
|
|
|
var synced = await controller.SyncCognitoUserAsync(
|
|
user.CognitoSub, email, user.DisplayName, UserRole.Admin, CancellationToken.None);
|
|
|
|
synced.Id.Should().Be(user.Id);
|
|
synced.Email.Should().Be(email);
|
|
synced.Role.Should().Be(UserRole.Admin);
|
|
logger.Messages.Should().ContainSingle();
|
|
logger.Messages[0].Should().Contain(user.Id.ToString());
|
|
logger.Messages[0].Should().NotContain(email);
|
|
logger.Messages[0].Should().Contain(UserRole.Dispatcher.ToString());
|
|
logger.Messages[0].Should().Contain(UserRole.Admin.ToString());
|
|
db.Dispose();
|
|
}
|
|
|
|
[Fact(DisplayName = "SEC-29: Cognito role sync does not log when role is unchanged")]
|
|
public async Task UnchangedRole_DoesNotLog()
|
|
{
|
|
var user = new User
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
CognitoSub = "sub-unchanged",
|
|
Email = "pii@example.com",
|
|
DisplayName = "Test User",
|
|
Role = UserRole.Admin,
|
|
IsActive = true,
|
|
CreatedAt = DateTime.UtcNow,
|
|
UpdatedAt = DateTime.UtcNow,
|
|
};
|
|
|
|
var (controller, db, logger) = CreateController(user);
|
|
|
|
await controller.SyncCognitoUserAsync(
|
|
user.CognitoSub, user.Email, user.DisplayName, UserRole.Admin, CancellationToken.None);
|
|
|
|
logger.Messages.Should().BeEmpty();
|
|
db.Dispose();
|
|
}
|
|
|
|
private static (AuthController Controller, Infrastructure.Data.ProposalDbContext Db, CapturingLogger<AuthController> Logger)
|
|
CreateController(User seed)
|
|
{
|
|
var db = DbContextFactory.Create();
|
|
db.Users.Add(seed);
|
|
db.SaveChanges();
|
|
|
|
var logger = new CapturingLogger<AuthController>();
|
|
var controller = new AuthController(
|
|
db,
|
|
Substitute.For<IHttpClientFactory>(),
|
|
new ConfigurationBuilder().Build(),
|
|
logger);
|
|
|
|
return (controller, db, logger);
|
|
}
|
|
}
|