From 5286b6b8e36f90339d6a2a0e7251ac0034c66433 Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Thu, 16 Apr 2026 06:49:00 +0300 Subject: [PATCH] [AZ-198] Block disabled user login Made-with: Cursor --- Azaion.Common/BusinessException.cs | 3 +++ Azaion.Services/UserService.cs | 3 +++ e2e/Azaion.E2E/Tests/SecurityTests.cs | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Azaion.Common/BusinessException.cs b/Azaion.Common/BusinessException.cs index 43033d6..1b7d0de 100644 --- a/Azaion.Common/BusinessException.cs +++ b/Azaion.Common/BusinessException.cs @@ -36,6 +36,9 @@ public enum ExceptionEnum WrongEmail = 37, + [Description("User account is disabled.")] + UserDisabled = 38, + [Description("Hardware mismatch! You are not authorized to access this resource from this hardware.")] HardwareIdMismatch = 40, diff --git a/Azaion.Services/UserService.cs b/Azaion.Services/UserService.cs index baf0503..59f5f81 100644 --- a/Azaion.Services/UserService.cs +++ b/Azaion.Services/UserService.cs @@ -63,6 +63,9 @@ public class UserService(IDbFactory dbFactory, ICache cache) : IUserService if (request.Password.ToHash() != user.PasswordHash) throw new BusinessException(ExceptionEnum.WrongPassword); + if (!user.IsEnabled) + throw new BusinessException(ExceptionEnum.UserDisabled); + return user; }); diff --git a/e2e/Azaion.E2E/Tests/SecurityTests.cs b/e2e/Azaion.E2E/Tests/SecurityTests.cs index 9775d36..02e4e06 100644 --- a/e2e/Azaion.E2E/Tests/SecurityTests.cs +++ b/e2e/Azaion.E2E/Tests/SecurityTests.cs @@ -19,6 +19,13 @@ public sealed class SecurityTests PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + private static readonly JsonSerializerOptions ResponseJsonOptions = new() + { + PropertyNameCaseInsensitive = true + }; + + private sealed record ErrorResponse(int ErrorCode, string Message); + private readonly TestFixture _fixture; public SecurityTests(TestFixture fixture) => _fixture = fixture; @@ -195,7 +202,7 @@ public sealed class SecurityTests } } - [Fact(Skip = "API bug: login does not check IsEnabled — disabled users can still log in")] + [Fact] public async Task Disabled_user_cannot_log_in() { // Arrange @@ -218,7 +225,10 @@ public sealed class SecurityTests using var login = await client.PostAsync("/login", new { email, password }); // Assert - login.StatusCode.Should().BeOneOf(HttpStatusCode.Forbidden, HttpStatusCode.Conflict); + login.StatusCode.Should().Be(HttpStatusCode.Conflict); + var err = await login.Content.ReadFromJsonAsync(ResponseJsonOptions); + err.Should().NotBeNull(); + err!.ErrorCode.Should().Be(38); } finally {