diff --git a/NEW/tests/JdeScoping.Api.Tests/Controllers/AuthControllerTests.cs b/NEW/tests/JdeScoping.Api.Tests/Controllers/AuthControllerTests.cs index 07f1500..66047f1 100644 --- a/NEW/tests/JdeScoping.Api.Tests/Controllers/AuthControllerTests.cs +++ b/NEW/tests/JdeScoping.Api.Tests/Controllers/AuthControllerTests.cs @@ -1,8 +1,12 @@ +// NEW/tests/JdeScoping.Api.Tests/Controllers/AuthControllerTests.cs using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Text.Json; using JdeScoping.Api.Controllers; -using JdeScoping.Api.Models; using JdeScoping.Core.Interfaces; using JdeScoping.Core.Models; +using JdeScoping.Core.Models.Auth; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -15,21 +19,58 @@ namespace JdeScoping.Api.Tests.Controllers; public class AuthControllerTests { private readonly IAuthService _authService; + private readonly IRsaKeyService _rsaKeyService; private readonly ILogger _logger; private readonly AuthController _controller; + private readonly RSA _testRsa; public AuthControllerTests() { _authService = Substitute.For(); + _rsaKeyService = Substitute.For(); _logger = Substitute.For>(); - _controller = new AuthController(_authService, _logger); + + // Setup test RSA key pair + _testRsa = RSA.Create(2048); + var publicKeyPem = _testRsa.ExportSubjectPublicKeyInfoPem(); + _rsaKeyService.GetPublicKeyPem().Returns(publicKeyPem); + _rsaKeyService.Decrypt(Arg.Any()) + .Returns(callInfo => + { + var ciphertext = callInfo.Arg(); + return _testRsa.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256); + }); + + _controller = new AuthController(_authService, _rsaKeyService, _logger); + } + + private EncryptedLoginRequest EncryptLoginModel(LoginModel model) + { + var json = JsonSerializer.Serialize(model); + var plaintext = Encoding.UTF8.GetBytes(json); + var ciphertext = _testRsa.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256); + return new EncryptedLoginRequest(Convert.ToBase64String(ciphertext)); } [Fact] - public async Task Login_WithValidCredentials_ReturnsUserInfo() + public void GetPublicKey_ReturnsPublicKeyPem() + { + // Act + var result = _controller.GetPublicKey(); + + // Assert + result.Result.ShouldBeOfType(); + var okResult = (OkObjectResult)result.Result!; + var response = okResult.Value.ShouldBeOfType(); + response.PublicKeyPem.ShouldStartWith("-----BEGIN PUBLIC KEY-----"); + } + + [Fact] + public async Task Login_WithValidCredentials_ReturnsLoginResultWithUser() { // Arrange - var request = new LoginRequest { Username = "testuser", Password = "password123" }; + var loginModel = new LoginModel { Username = "testuser", Password = "password123" }; + var request = EncryptLoginModel(loginModel); var user = new UserInfo { Dn = "CN=testuser,DC=example,DC=com", @@ -42,7 +83,6 @@ public class AuthControllerTests _authService.AuthenticateAsync("testuser", "password123", Arg.Any()) .Returns(new AuthResult(true, user, null)); - // Setup HttpContext with mock authentication var httpContext = CreateMockHttpContext(); _controller.ControllerContext = new ControllerContext { HttpContext = httpContext }; @@ -52,20 +92,21 @@ public class AuthControllerTests // Assert result.Result.ShouldBeOfType(); var okResult = (OkObjectResult)result.Result!; - var returnedUser = okResult.Value.ShouldBeOfType(); - returnedUser.Username.ShouldBe("testuser"); - returnedUser.FirstName.ShouldBe("Test"); + var loginResult = okResult.Value.ShouldBeOfType(); + loginResult.Success.ShouldBeTrue(); + loginResult.User.ShouldNotBeNull(); + loginResult.User.Username.ShouldBe("testuser"); } [Fact] - public async Task Login_WithInvalidCredentials_Returns401() + public async Task Login_WithInvalidCredentials_Returns401WithError() { // Arrange - var request = new LoginRequest { Username = "testuser", Password = "wrongpassword" }; + var loginModel = new LoginModel { Username = "testuser", Password = "wrongpassword" }; + var request = EncryptLoginModel(loginModel); _authService.AuthenticateAsync("testuser", "wrongpassword", Arg.Any()) .Returns(new AuthResult(false, null, "Incorrect username or password")); - // Setup HttpContext var httpContext = CreateMockHttpContext(); _controller.ControllerContext = new ControllerContext { HttpContext = httpContext }; @@ -74,6 +115,30 @@ public class AuthControllerTests // Assert result.Result.ShouldBeOfType(); + var unauthorizedResult = (UnauthorizedObjectResult)result.Result!; + var loginResult = unauthorizedResult.Value.ShouldBeOfType(); + loginResult.Success.ShouldBeFalse(); + loginResult.ErrorMessage.ShouldBe("Incorrect username or password"); + } + + [Fact] + public async Task Login_WithInvalidEncryptedData_ReturnsBadRequest() + { + // Arrange + var request = new EncryptedLoginRequest("not-valid-base64!!!"); + + var httpContext = CreateMockHttpContext(); + _controller.ControllerContext = new ControllerContext { HttpContext = httpContext }; + + // Act + var result = await _controller.Login(request, CancellationToken.None); + + // Assert + result.Result.ShouldBeOfType(); + var badRequestResult = (BadRequestObjectResult)result.Result!; + var loginResult = badRequestResult.Value.ShouldBeOfType(); + loginResult.Success.ShouldBeFalse(); + loginResult.ErrorMessage.ShouldBe("Invalid encrypted payload"); } [Fact] @@ -119,42 +184,6 @@ public class AuthControllerTests user.Username.ShouldBe("testuser"); } - [Fact] - public void GetCurrentUser_ExtractsAllClaimsCorrectly() - { - // Arrange - var claims = new List - { - new(ClaimTypes.Name, "jsmith"), - new(ClaimTypes.GivenName, "John"), - new(ClaimTypes.Surname, "Smith"), - new(ClaimTypes.Email, "jsmith@example.com"), - new("title", "Senior Engineer"), - new("dn", "CN=jsmith,OU=Users,DC=example,DC=com") - }; - var identity = new ClaimsIdentity(claims, "Test"); - var principal = new ClaimsPrincipal(identity); - - var httpContext = new DefaultHttpContext { User = principal }; - _controller.ControllerContext = new ControllerContext { HttpContext = httpContext }; - - // Act - var result = _controller.GetCurrentUser(); - - // Assert - result.Result.ShouldBeOfType(); - var okResult = (OkObjectResult)result.Result!; - var user = okResult.Value.ShouldBeOfType(); - - user.Username.ShouldBe("jsmith"); - user.FirstName.ShouldBe("John"); - user.LastName.ShouldBe("Smith"); - user.EmailAddress.ShouldBe("jsmith@example.com"); - user.Title.ShouldBe("Senior Engineer"); - user.Dn.ShouldBe("CN=jsmith,OU=Users,DC=example,DC=com"); - user.DisplayName.ShouldBe("John Smith"); - } - private static HttpContext CreateMockHttpContext() { var authServiceMock = Substitute.For();