From 14d9b454134dfed848cf82f01d787ca9ee038762 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Mon, 16 Jun 2025 22:43:02 +0200 Subject: [PATCH 01/20] Added strong password validation --- MainProject.Tests/MainProject.Tests.csproj | 13 ++-- MainProject.Tests/Utils/PasswordUtils_Test.cs | 62 +++++++++++++++++++ MainProject/Enum/PasswordValidationEnum.cs | 10 +++ MainProject/MainProject.csproj | 18 +++--- MainProject/Utils/PasswordUtils.cs | 60 ++++++++++++++++++ 5 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 MainProject.Tests/Utils/PasswordUtils_Test.cs create mode 100644 MainProject/Enum/PasswordValidationEnum.cs create mode 100644 MainProject/Utils/PasswordUtils.cs diff --git a/MainProject.Tests/MainProject.Tests.csproj b/MainProject.Tests/MainProject.Tests.csproj index 45f0343..b083669 100644 --- a/MainProject.Tests/MainProject.Tests.csproj +++ b/MainProject.Tests/MainProject.Tests.csproj @@ -10,12 +10,15 @@ - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + - - + + diff --git a/MainProject.Tests/Utils/PasswordUtils_Test.cs b/MainProject.Tests/Utils/PasswordUtils_Test.cs new file mode 100644 index 0000000..2f2d6e6 --- /dev/null +++ b/MainProject.Tests/Utils/PasswordUtils_Test.cs @@ -0,0 +1,62 @@ +using BasicDotnetTemplate.MainProject.Utils; +using BasicDotnetTemplate.MainProject.Models.Common; +using BasicDotnetTemplate.MainProject.Enum; + + +namespace BasicDotnetTemplate.MainProject.Tests; + +[TestClass] +public class PasswordUtils_Test +{ + [TestMethod] + public void PasswordValidation_Valid() + { + try + { + List errors = PasswordUtils.ValidatePassword("#aBcDeFgHi01245#"); + Assert.IsTrue(errors == null || errors.Count == 0); + } + catch (Exception exception) + { + Assert.Fail($"An exception was thrown: {exception}"); + } + } + + [TestMethod] + public void PasswordValidation_Invalid() + { + try + { + List errors = PasswordUtils.ValidatePassword("aAa1#"); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_LENGTH)); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_UPPER)); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_NUMBER)); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_SPECIAL)); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.IDENTICAL_CHARS)); + Assert.IsTrue(!errors.Contains(PasswordValidationEnum.MIN_LOWER)); + } + catch (Exception exception) + { + Assert.Fail($"An exception was thrown: {exception}"); + } + } + + [TestMethod] + public void PasswordValidation_ToLowerInvalid() + { + try + { + List errors = PasswordUtils.ValidatePassword("AaBC0*TGH1#"); + Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_LOWER)); + } + catch (Exception exception) + { + Assert.Fail($"An exception was thrown: {exception}"); + } + } + +} + + + + diff --git a/MainProject/Enum/PasswordValidationEnum.cs b/MainProject/Enum/PasswordValidationEnum.cs new file mode 100644 index 0000000..b821805 --- /dev/null +++ b/MainProject/Enum/PasswordValidationEnum.cs @@ -0,0 +1,10 @@ +namespace BasicDotnetTemplate.MainProject.Enum; +public static class PasswordValidationEnum +{ + public const string MIN_LENGTH = "Password must be at least 8 characters long"; + public const string MIN_UPPER = "Password must have at least 2 uppercase letters"; + public const string MIN_LOWER = "Password must have at least 2 lowercase letters"; + public const string MIN_NUMBER = "Password must be at least 2 numbers"; + public const string MIN_SPECIAL = "Password must be at least 2 special characters"; + public const string IDENTICAL_CHARS = "Password cannot have 3 or more consecutive identical characters"; +} diff --git a/MainProject/MainProject.csproj b/MainProject/MainProject.csproj index 24c681d..801b05c 100644 --- a/MainProject/MainProject.csproj +++ b/MainProject/MainProject.csproj @@ -30,21 +30,21 @@ all - + - - + + - - + + - - - - + + + + diff --git a/MainProject/Utils/PasswordUtils.cs b/MainProject/Utils/PasswordUtils.cs new file mode 100644 index 0000000..25e28e1 --- /dev/null +++ b/MainProject/Utils/PasswordUtils.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using BasicDotnetTemplate.MainProject.Enum; +using BasicDotnetTemplate.MainProject.Models.Settings; + +namespace BasicDotnetTemplate.MainProject.Utils; +public partial class PasswordUtils +{ + private const int MIN_LENGTH = 8; + private const int MIN_UPPER = 2; + private const int MIN_LOWER = 2; + private const int MIN_NUMBER = 2; + private const int MIN_SPECIAL = 2; + + [GeneratedRegex("[A-Z]")] + private static partial Regex RegexUpper(); + + [GeneratedRegex("[a-z]")] + private static partial Regex RegexLower(); + + [GeneratedRegex("[0-9]")] + private static partial Regex RegexNumber(); + + [GeneratedRegex("[^a-zA-Z0-9]")] + private static partial Regex RegexSpecial(); + + [GeneratedRegex(@"(\S)\1{2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled)] + private static partial Regex RegexIdenticalChars(); + + public static List ValidatePassword(string password) + { + List errors = []; + + if (password.Length < 8) + errors.Add(PasswordValidationEnum.MIN_LENGTH); + + if (RegexUpper().Matches(password).Count < MIN_UPPER) + errors.Add(PasswordValidationEnum.MIN_UPPER); + + if (RegexLower().Matches(password).Count < MIN_LOWER) + errors.Add(PasswordValidationEnum.MIN_LOWER); + + if (RegexNumber().Matches(password).Count < MIN_NUMBER) + errors.Add(PasswordValidationEnum.MIN_NUMBER); + + if (RegexSpecial().Matches(password).Count < MIN_SPECIAL) + errors.Add(PasswordValidationEnum.MIN_SPECIAL); + + if (RegexIdenticalChars().IsMatch(password)) + errors.Add(PasswordValidationEnum.IDENTICAL_CHARS); + + return errors; + } + + +} + From 1877c29e689d66fc4db4d3910fc13b7bf126b774 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 00:01:29 +0200 Subject: [PATCH 02/20] Fixing user password generation/validation - wip --- MainProject.Tests/JsonData/appsettings.json | 5 +-- .../JsonData/invalidCryptAppsettings.json | 5 +-- MainProject.Tests/TestsUtils/ModelsInit.cs | 3 +- ...yptoUtils_Tests.cs => CryptUtils_Tests.cs} | 19 +++++----- MainProject/Models/Database/SqlServer/User.cs | 5 ++- .../Models/Settings/EncryptionSettings.cs | 3 +- MainProject/Services/UserService.cs | 15 +++++--- .../Utils/{CryptoUtils.cs => CryptUtils.cs} | 35 ++++++++----------- MainProject/appsettings.json | 5 +-- 9 files changed, 50 insertions(+), 45 deletions(-) rename MainProject.Tests/Utils/{CryptoUtils_Tests.cs => CryptUtils_Tests.cs} (87%) rename MainProject/Utils/{CryptoUtils.cs => CryptUtils.cs} (65%) diff --git a/MainProject.Tests/JsonData/appsettings.json b/MainProject.Tests/JsonData/appsettings.json index a8fa93d..97b4013 100644 --- a/MainProject.Tests/JsonData/appsettings.json +++ b/MainProject.Tests/JsonData/appsettings.json @@ -35,8 +35,9 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Salt": "S7VIidfXQf1tOQYX", - "Pepper": "" + "Secret": "S7VIidfXQf1tOQYX", + "Salt": "", + "Iterations": 10 } } diff --git a/MainProject.Tests/JsonData/invalidCryptAppsettings.json b/MainProject.Tests/JsonData/invalidCryptAppsettings.json index bb290e6..293760b 100644 --- a/MainProject.Tests/JsonData/invalidCryptAppsettings.json +++ b/MainProject.Tests/JsonData/invalidCryptAppsettings.json @@ -35,8 +35,9 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Salt": "AAAAA", - "Pepper": "" + "Secret": "AAAAA", + "Salt": "", + "Iterations": 10 } } diff --git a/MainProject.Tests/TestsUtils/ModelsInit.cs b/MainProject.Tests/TestsUtils/ModelsInit.cs index 29541ff..d97f11b 100644 --- a/MainProject.Tests/TestsUtils/ModelsInit.cs +++ b/MainProject.Tests/TestsUtils/ModelsInit.cs @@ -13,8 +13,9 @@ public static class ModelsInit FirstName = "FirstName", LastName = "LastName", Email = "test-new@email.it", - PasswordHash = "PasswordHash", + PasswordPepper = "PasswordPepper", PasswordSalt = "PasswordSalt", + PasswordIterations = 0, Password = "Password", Role = CreateRole(), IsTestUser = true diff --git a/MainProject.Tests/Utils/CryptoUtils_Tests.cs b/MainProject.Tests/Utils/CryptUtils_Tests.cs similarity index 87% rename from MainProject.Tests/Utils/CryptoUtils_Tests.cs rename to MainProject.Tests/Utils/CryptUtils_Tests.cs index c054658..d29e343 100644 --- a/MainProject.Tests/Utils/CryptoUtils_Tests.cs +++ b/MainProject.Tests/Utils/CryptUtils_Tests.cs @@ -102,11 +102,11 @@ public class CryptoUtils_Tests } [TestMethod] - public void GenerateSalt() + public void GeneratePepper() { try { - var salt = CryptUtils.GenerateSalt(); + var salt = CryptUtils.GeneratePepper(); Assert.IsTrue(!String.IsNullOrEmpty(salt)); } catch (Exception ex) @@ -122,14 +122,14 @@ public class CryptoUtils_Tests try { var password = "P4ssw0rd@1!"; - var salt = CryptUtils.GenerateSalt(); - Assert.IsTrue(!String.IsNullOrEmpty(salt)); + var pepper = CryptUtils.GeneratePepper(); + Assert.IsTrue(!String.IsNullOrEmpty(pepper)); WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty()); AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData"); - CryptUtils cryptoUtils = new CryptUtils(appSettings); - var encryptedPassword = cryptoUtils.GeneratePassword(password, salt, 0); - Assert.IsTrue(password != encryptedPassword); + var salt = appSettings?.EncryptionSettings?.Salt ?? String.Empty; + var encryptedPassword = CryptUtils.GeneratePassword(password, salt, 0, pepper); + Assert.AreNotEqual(encryptedPassword, password); } catch (Exception ex) { @@ -147,10 +147,7 @@ public class CryptoUtils_Tests var salt = "Afi7PQYgEL2sPbNyVzduvg=="; var hashedPassword = "2lMeySZ9ciH1KtSg1Z7oSJRmJEjHMeDvdaNRcJcGutM="; - WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty()); - AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData"); - CryptUtils cryptoUtils = new CryptUtils(appSettings); - var verified = cryptoUtils.VerifyPassword(password, salt, 0, hashedPassword); + var verified = CryptUtils.VerifyPassword(hashedPassword, password, salt, 0); Assert.IsTrue(verified); } catch (Exception ex) diff --git a/MainProject/Models/Database/SqlServer/User.cs b/MainProject/Models/Database/SqlServer/User.cs index 3bb8f97..8d5fff6 100644 --- a/MainProject/Models/Database/SqlServer/User.cs +++ b/MainProject/Models/Database/SqlServer/User.cs @@ -13,7 +13,10 @@ public class User : Base [MaxLength(200)] public required string Email { get; set; } public required string PasswordSalt { get; set; } - public required string PasswordHash { get; set; } +#nullable enable + public string? PasswordPepper { get; set; } +#nullable disable + public required int PasswordIterations { get; set; } public required Role Role { get; set; } public required bool IsTestUser { get; set; } diff --git a/MainProject/Models/Settings/EncryptionSettings.cs b/MainProject/Models/Settings/EncryptionSettings.cs index 8d40260..a7a0106 100644 --- a/MainProject/Models/Settings/EncryptionSettings.cs +++ b/MainProject/Models/Settings/EncryptionSettings.cs @@ -3,7 +3,8 @@ namespace BasicDotnetTemplate.MainProject.Models.Settings; public class EncryptionSettings { #nullable enable + public string? Secret { get; set; } public string? Salt { get; set; } - public string? Pepper { get; set; } + public int? Iterations { get; set; } #nullable disable } \ No newline at end of file diff --git a/MainProject/Services/UserService.cs b/MainProject/Services/UserService.cs index 3fe1314..99a6a09 100644 --- a/MainProject/Services/UserService.cs +++ b/MainProject/Services/UserService.cs @@ -4,6 +4,7 @@ using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Models.Api.Common.Exceptions; using BasicDotnetTemplate.MainProject.Models.Api.Data.User; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; +using BasicDotnetTemplate.MainProject.Utils; using Microsoft.EntityFrameworkCore; namespace BasicDotnetTemplate.MainProject.Services; @@ -21,12 +22,15 @@ public interface IUserService public class UserService : BaseService, IUserService { private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + private readonly CryptUtils _cryptUtils; public UserService( IHttpContextAccessor httpContextAccessor, IConfiguration configuration, SqlServerContext sqlServerContext ) : base(httpContextAccessor, configuration, sqlServerContext) - { } + { + this._cryptUtils = new(_appSettings); + } private IQueryable GetUsersQueryable() { @@ -51,8 +55,9 @@ public class UserService : BaseService, IUserService FirstName = data.FirstName, LastName = data.LastName, Email = data.Email, - PasswordSalt = "", - PasswordHash = "", + PasswordSalt = _appSettings.EncryptionSettings?.Salt ?? String.Empty, + PasswordPepper = CryptUtils.GeneratePepper(), + PasswordIterations = _appSettings.EncryptionSettings?.Iterations ?? 10, Password = "", Role = role, IsTestUser = false @@ -77,7 +82,9 @@ public class UserService : BaseService, IUserService User? user = await this.GetUserByEmailQueryable(email).FirstOrDefaultAsync(); if (user != null) { - var encryptedPassword = user.PasswordHash; + var valid = CryptUtils.VerifyPassword(user.Password, password, user.PasswordSalt, user.PasswordIterations, user.PasswordPepper); + if (!valid) + user = null; } return user; diff --git a/MainProject/Utils/CryptoUtils.cs b/MainProject/Utils/CryptUtils.cs similarity index 65% rename from MainProject/Utils/CryptoUtils.cs rename to MainProject/Utils/CryptUtils.cs index cb847fc..75b9862 100644 --- a/MainProject/Utils/CryptoUtils.cs +++ b/MainProject/Utils/CryptUtils.cs @@ -4,24 +4,17 @@ using System.Text; using BasicDotnetTemplate.MainProject.Models.Settings; namespace BasicDotnetTemplate.MainProject.Utils; -public class CryptUtils +public class CryptUtils(AppSettings appSettings) { - private readonly string _secretKey; - private readonly string _pepper; + private readonly string _secret = appSettings.EncryptionSettings?.Secret ?? String.Empty; private const int _M = 16; private const int _N = 32; - public CryptUtils(AppSettings appSettings) - { - _secretKey = appSettings.EncryptionSettings?.Salt ?? String.Empty; - _pepper = appSettings.EncryptionSettings?.Pepper ?? String.Empty; - } - public string Decrypt(string encryptedData) { var decrypted = String.Empty; - if (String.IsNullOrEmpty(this._secretKey) || this._secretKey.Length < _M) + if (String.IsNullOrEmpty(this._secret) || this._secret.Length < _M) { throw new ArgumentException("Unable to proceed with decryption due to invalid settings"); } @@ -35,7 +28,7 @@ public class CryptUtils using (var aes = Aes.Create()) { - aes.Key = Encoding.UTF8.GetBytes(this._secretKey); + aes.Key = Encoding.UTF8.GetBytes(this._secret); aes.IV = Encoding.UTF8.GetBytes(iv); using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV)) @@ -57,21 +50,21 @@ public class CryptUtils return decrypted; } - public static string GenerateSalt() + public static string GeneratePepper() { using var rng = RandomNumberGenerator.Create(); - var byteSalt = new byte[16]; - rng.GetBytes(byteSalt); - var salt = Convert.ToBase64String(byteSalt); - return salt; + var bytePepper = new byte[16]; + rng.GetBytes(bytePepper); + var pepper = Convert.ToBase64String(bytePepper); + return pepper; } - public string GeneratePassword(string password, string salt, int iteration) + public static string GeneratePassword(string password, string salt, int iterations, string? pepper = "") { string hashedPassword = password; - for(var i = 0; i <= iteration; i++) + for (var i = 0; i <= iterations; i++) { - var passwordSaltPepper = $"{hashedPassword}{salt}{this._pepper}"; + var passwordSaltPepper = $"{hashedPassword}{salt}{pepper}"; var byteValue = Encoding.UTF8.GetBytes(passwordSaltPepper); var byteHash = SHA256.HashData(byteValue); hashedPassword = Convert.ToBase64String(byteHash); @@ -80,9 +73,9 @@ public class CryptUtils return hashedPassword; } - public bool VerifyPassword(string password, string salt, int iteration, string userPassword) + public static bool VerifyPassword(string userPassword, string password, string salt, int iterations, string? pepper = "") { - string hashedPassword = this.GeneratePassword(password, salt, iteration); + string hashedPassword = GeneratePassword(password, salt, iterations, pepper); return hashedPassword.Equals(userPassword, StringComparison.OrdinalIgnoreCase); } diff --git a/MainProject/appsettings.json b/MainProject/appsettings.json index 8893bf2..7063e68 100644 --- a/MainProject/appsettings.json +++ b/MainProject/appsettings.json @@ -35,8 +35,9 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Salt": "S7VIidfXQf1tOQYX", - "Pepper": "" + "Secret": "S7VIidfXQf1tOQYX", + "Salt": "", + "Iterations": 10 }, "PermissionsSettings": { "FilePath": "Config/permissions.json" From ad1909ef57ff45be116c8c8a8064c4e00278f620 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 00:11:14 +0200 Subject: [PATCH 03/20] Minor fixes --- MainProject.Tests/Utils/PasswordUtils_Test.cs | 2 +- MainProject/Utils/PasswordUtils.cs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/MainProject.Tests/Utils/PasswordUtils_Test.cs b/MainProject.Tests/Utils/PasswordUtils_Test.cs index 2f2d6e6..937a367 100644 --- a/MainProject.Tests/Utils/PasswordUtils_Test.cs +++ b/MainProject.Tests/Utils/PasswordUtils_Test.cs @@ -33,7 +33,7 @@ public class PasswordUtils_Test Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_NUMBER)); Assert.IsTrue(errors.Contains(PasswordValidationEnum.MIN_SPECIAL)); Assert.IsTrue(errors.Contains(PasswordValidationEnum.IDENTICAL_CHARS)); - Assert.IsTrue(!errors.Contains(PasswordValidationEnum.MIN_LOWER)); + Assert.IsFalse(errors.Contains(PasswordValidationEnum.MIN_LOWER)); } catch (Exception exception) { diff --git a/MainProject/Utils/PasswordUtils.cs b/MainProject/Utils/PasswordUtils.cs index 25e28e1..e72bde3 100644 --- a/MainProject/Utils/PasswordUtils.cs +++ b/MainProject/Utils/PasswordUtils.cs @@ -9,6 +9,8 @@ using BasicDotnetTemplate.MainProject.Models.Settings; namespace BasicDotnetTemplate.MainProject.Utils; public partial class PasswordUtils { + protected PasswordUtils() { } + private const int MIN_LENGTH = 8; private const int MIN_UPPER = 2; private const int MIN_LOWER = 2; @@ -27,14 +29,13 @@ public partial class PasswordUtils [GeneratedRegex("[^a-zA-Z0-9]")] private static partial Regex RegexSpecial(); - [GeneratedRegex(@"(\S)\1{2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled)] - private static partial Regex RegexIdenticalChars(); + private static readonly Regex RegexIdenticalChars = new(@"(\S)\1{2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled); public static List ValidatePassword(string password) { List errors = []; - if (password.Length < 8) + if (password.Length < MIN_LENGTH) errors.Add(PasswordValidationEnum.MIN_LENGTH); if (RegexUpper().Matches(password).Count < MIN_UPPER) @@ -49,7 +50,7 @@ public partial class PasswordUtils if (RegexSpecial().Matches(password).Count < MIN_SPECIAL) errors.Add(PasswordValidationEnum.MIN_SPECIAL); - if (RegexIdenticalChars().IsMatch(password)) + if (RegexIdenticalChars.IsMatch(password)) errors.Add(PasswordValidationEnum.IDENTICAL_CHARS); return errors; From 11a9696bdd5cfc6c15642a9898884eae510547bd Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 19:47:56 +0200 Subject: [PATCH 04/20] Fixing security hotspots + issues --- MainProject.Tests/JsonData/appsettings.json | 2 +- MainProject.Tests/JsonData/invalidCryptAppsettings.json | 2 +- MainProject/Models/Settings/EncryptionSettings.cs | 2 +- MainProject/Services/UserService.cs | 5 +---- MainProject/Utils/CryptUtils.cs | 6 +++--- MainProject/Utils/PasswordUtils.cs | 6 +++++- MainProject/appsettings.json | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/MainProject.Tests/JsonData/appsettings.json b/MainProject.Tests/JsonData/appsettings.json index 97b4013..6bd1180 100644 --- a/MainProject.Tests/JsonData/appsettings.json +++ b/MainProject.Tests/JsonData/appsettings.json @@ -35,7 +35,7 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Secret": "S7VIidfXQf1tOQYX", + "SaltKey": "S7VIidfXQf1tOQYX", "Salt": "", "Iterations": 10 } diff --git a/MainProject.Tests/JsonData/invalidCryptAppsettings.json b/MainProject.Tests/JsonData/invalidCryptAppsettings.json index 293760b..e7d6f9e 100644 --- a/MainProject.Tests/JsonData/invalidCryptAppsettings.json +++ b/MainProject.Tests/JsonData/invalidCryptAppsettings.json @@ -35,7 +35,7 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Secret": "AAAAA", + "SaltKey": "AAAAA", "Salt": "", "Iterations": 10 } diff --git a/MainProject/Models/Settings/EncryptionSettings.cs b/MainProject/Models/Settings/EncryptionSettings.cs index a7a0106..0a03110 100644 --- a/MainProject/Models/Settings/EncryptionSettings.cs +++ b/MainProject/Models/Settings/EncryptionSettings.cs @@ -3,7 +3,7 @@ namespace BasicDotnetTemplate.MainProject.Models.Settings; public class EncryptionSettings { #nullable enable - public string? Secret { get; set; } + public string? SaltKey { get; set; } public string? Salt { get; set; } public int? Iterations { get; set; } #nullable disable diff --git a/MainProject/Services/UserService.cs b/MainProject/Services/UserService.cs index 99a6a09..f7e1644 100644 --- a/MainProject/Services/UserService.cs +++ b/MainProject/Services/UserService.cs @@ -22,15 +22,12 @@ public interface IUserService public class UserService : BaseService, IUserService { private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - private readonly CryptUtils _cryptUtils; public UserService( IHttpContextAccessor httpContextAccessor, IConfiguration configuration, SqlServerContext sqlServerContext ) : base(httpContextAccessor, configuration, sqlServerContext) - { - this._cryptUtils = new(_appSettings); - } + { } private IQueryable GetUsersQueryable() { diff --git a/MainProject/Utils/CryptUtils.cs b/MainProject/Utils/CryptUtils.cs index 75b9862..259f1e0 100644 --- a/MainProject/Utils/CryptUtils.cs +++ b/MainProject/Utils/CryptUtils.cs @@ -6,7 +6,7 @@ using BasicDotnetTemplate.MainProject.Models.Settings; namespace BasicDotnetTemplate.MainProject.Utils; public class CryptUtils(AppSettings appSettings) { - private readonly string _secret = appSettings.EncryptionSettings?.Secret ?? String.Empty; + private readonly string _saltKey = appSettings.EncryptionSettings?.SaltKey ?? String.Empty; private const int _M = 16; private const int _N = 32; @@ -14,7 +14,7 @@ public class CryptUtils(AppSettings appSettings) { var decrypted = String.Empty; - if (String.IsNullOrEmpty(this._secret) || this._secret.Length < _M) + if (String.IsNullOrEmpty(this._saltKey) || this._saltKey.Length < _M) { throw new ArgumentException("Unable to proceed with decryption due to invalid settings"); } @@ -28,7 +28,7 @@ public class CryptUtils(AppSettings appSettings) using (var aes = Aes.Create()) { - aes.Key = Encoding.UTF8.GetBytes(this._secret); + aes.Key = Encoding.UTF8.GetBytes(this._saltKey); aes.IV = Encoding.UTF8.GetBytes(iv); using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV)) diff --git a/MainProject/Utils/PasswordUtils.cs b/MainProject/Utils/PasswordUtils.cs index e72bde3..8deb1d3 100644 --- a/MainProject/Utils/PasswordUtils.cs +++ b/MainProject/Utils/PasswordUtils.cs @@ -29,7 +29,11 @@ public partial class PasswordUtils [GeneratedRegex("[^a-zA-Z0-9]")] private static partial Regex RegexSpecial(); - private static readonly Regex RegexIdenticalChars = new(@"(\S)\1{2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex RegexIdenticalChars = new( + @"(\S)\1{2,}", + RegexOptions.IgnoreCase | RegexOptions.Compiled, + TimeSpan.FromMilliseconds(100) + ); public static List ValidatePassword(string password) { diff --git a/MainProject/appsettings.json b/MainProject/appsettings.json index 7063e68..dde36ef 100644 --- a/MainProject/appsettings.json +++ b/MainProject/appsettings.json @@ -35,7 +35,7 @@ "ExpiredAfterMinsOfInactivity": 15 }, "EncryptionSettings": { - "Secret": "S7VIidfXQf1tOQYX", + "SaltKey": "S7VIidfXQf1tOQYX", "Salt": "", "Iterations": 10 }, From 061ce4cb3d7eb88a622f654af480af458c188b5d Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 19:58:02 +0200 Subject: [PATCH 05/20] Fixed issues "Do not negate boolean assertions, instead use the opposite assertion" --- MainProject.Tests/Utils/CryptUtils_Tests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MainProject.Tests/Utils/CryptUtils_Tests.cs b/MainProject.Tests/Utils/CryptUtils_Tests.cs index d29e343..ad27193 100644 --- a/MainProject.Tests/Utils/CryptUtils_Tests.cs +++ b/MainProject.Tests/Utils/CryptUtils_Tests.cs @@ -107,7 +107,7 @@ public class CryptoUtils_Tests try { var salt = CryptUtils.GeneratePepper(); - Assert.IsTrue(!String.IsNullOrEmpty(salt)); + Assert.IsFalse(String.IsNullOrEmpty(salt)); } catch (Exception ex) { @@ -123,7 +123,7 @@ public class CryptoUtils_Tests { var password = "P4ssw0rd@1!"; var pepper = CryptUtils.GeneratePepper(); - Assert.IsTrue(!String.IsNullOrEmpty(pepper)); + Assert.IsFalse(String.IsNullOrEmpty(pepper)); WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty()); AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData"); From 56a7e767855812f5a26765d445633b253ebb1bef Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 21:01:57 +0200 Subject: [PATCH 06/20] Fixed password generation --- MainProject.Tests/JsonData/appsettings.json | 2 +- .../Services/UserService_Tests.cs | 78 ++- ...ableUsersForPasswordEncryption.Designer.cs | 542 ++++++++++++++++++ ...12_AlterTableUsersForPasswordEncryption.cs | 109 ++++ .../SqlServerContextModelSnapshot.cs | 15 +- MainProject/Services/UserService.cs | 11 +- MainProject/Utils/PasswordUtils.cs | 5 +- MainProject/appsettings.json | 2 +- 8 files changed, 722 insertions(+), 42 deletions(-) create mode 100644 MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.Designer.cs create mode 100644 MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs diff --git a/MainProject.Tests/JsonData/appsettings.json b/MainProject.Tests/JsonData/appsettings.json index 6bd1180..2580e5b 100644 --- a/MainProject.Tests/JsonData/appsettings.json +++ b/MainProject.Tests/JsonData/appsettings.json @@ -36,7 +36,7 @@ }, "EncryptionSettings": { "SaltKey": "S7VIidfXQf1tOQYX", - "Salt": "", + "Salt": "u5CZAwq9vLGysC", "Iterations": 10 } } diff --git a/MainProject.Tests/Services/UserService_Tests.cs b/MainProject.Tests/Services/UserService_Tests.cs index c3bc21f..1d4c75f 100644 --- a/MainProject.Tests/Services/UserService_Tests.cs +++ b/MainProject.Tests/Services/UserService_Tests.cs @@ -34,30 +34,7 @@ public class UserService_Tests Console.WriteLine(ex.InnerException); Assert.Fail($"An exception was thrown: {ex.Message}"); } - } - - [TestMethod] - public async Task GetUserByUsernameAndPassword_Null() - { - try - { - var testString = "test"; - if (_userService != null) - { - var user = await _userService.GetUserByUsernameAndPassword(testString, testString); - Assert.IsTrue(user == null); - } - else - { - Assert.Fail($"UserService is null"); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.InnerException); - Assert.Fail($"An exception was thrown: {ex}"); - } - } + } [TestMethod] public async Task CheckIfEmailIsValid_EmailNotExists() @@ -93,7 +70,8 @@ public class UserService_Tests { FirstName = expectedUser.FirstName ?? String.Empty, LastName = expectedUser.LastName ?? String.Empty, - Email = expectedUser.Email ?? String.Empty + Email = expectedUser.Email ?? String.Empty, + Password = "Password" }; Role role = new() @@ -110,6 +88,10 @@ public class UserService_Tests Assert.IsTrue(expectedUser.LastName == user.LastName); Assert.IsTrue(expectedUser.Email == user.Email); Assert.IsTrue(expectedUser.Role?.Name == user.Role?.Name); + Assert.IsTrue(user.PasswordIterations == 10); + Assert.IsNotNull(expectedUser.PasswordSalt); + Assert.IsNotNull(expectedUser.PasswordPepper); + Assert.IsNotNull(expectedUser.Password); _user = user; } @@ -120,6 +102,52 @@ public class UserService_Tests } } + [TestMethod] + public async Task GetUserByUsernameAndPassword_Null() + { + try + { + var testString = "test"; + if (_userService != null) + { + var user = await _userService.GetUserByUsernameAndPassword(testString, testString); + Assert.IsTrue(user == null); + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.InnerException); + Assert.Fail($"An exception was thrown: {ex}"); + } + } + + [TestMethod] + public async Task GetUserByUsernameAndPassword_Success() + { + try + { + var password = "Password"; + if (_userService != null) + { + var user = await _userService.GetUserByUsernameAndPassword(_user.Email, password); + Assert.IsTrue(user != null); + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.InnerException); + Assert.Fail($"An exception was thrown: {ex}"); + } + } + [TestMethod] public async Task CreateUserAsync_Exception() { diff --git a/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.Designer.cs b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.Designer.cs new file mode 100644 index 0000000..53baad2 --- /dev/null +++ b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.Designer.cs @@ -0,0 +1,542 @@ +// +using System; +using BasicDotnetTemplate.MainProject.Core.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MainProject.Migrations +{ + [DbContext(typeof(SqlServerContext))] + [Migration("20250617183212_AlterTableUsersForPasswordEncryption")] + partial class AlterTableUsersForPasswordEncryption + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionModule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "Enabled" }, "IX_Enabled") + .HasFilter("[Enabled] = 1"); + + b.HasIndex(new[] { "IsDeleted" }, "IX_IsDeleted") + .HasFilter("[IsDeleted] = 0"); + + b.HasIndex(new[] { "IsDeleted", "Name", "Enabled" }, "IX_IsDeleted_Name_Enabled") + .HasFilter("[IsDeleted] = 0"); + + b.ToTable("PermissionModules"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "IsDeleted", "Name" }, "IX_IsDeleted_Name"); + + b.ToTable("PermissionOperations"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "Enabled" }, "IX_Enabled") + .HasFilter("[Enabled] = 1"); + + b.HasIndex(new[] { "IsDeleted" }, "IX_IsDeleted") + .HasFilter("[IsDeleted] = 0"); + + b.HasIndex(new[] { "IsDeleted", "Name", "Enabled" }, "IX_IsDeleted_Name_Enabled") + .HasFilter("[IsDeleted] = 0"); + + b.ToTable("PermissionSystems"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PermissionModuleId") + .HasColumnType("int"); + + b.Property("PermissionSystemId") + .HasColumnType("int"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PermissionModuleId"); + + b.HasIndex("PermissionSystemId"); + + b.ToTable("PermissionSystemModules"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModuleOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PermissionOperationId") + .HasColumnType("int"); + + b.Property("PermissionSystemModuleId") + .HasColumnType("int"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PermissionOperationId"); + + b.HasIndex("PermissionSystemModuleId"); + + b.HasIndex(new[] { "IsDeleted", "Enabled", "Guid" }, "IX_IsDeleted_Enabled_Guid"); + + b.ToTable("PermissionSystemModuleOperations"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsNotEditable") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "IsDeleted", "Guid" }, "IX_IsDeleted_Guid") + .HasFilter("[IsDeleted] = 0"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.RolePermissionSystemModuleOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("bit"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PermissionSystemModuleOperationId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PermissionSystemModuleOperationId"); + + b.HasIndex("RoleId"); + + b.ToTable("RolePermissionSystemModuleOperations"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreationUserId") + .HasColumnType("int"); + + b.Property("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DeletionUserId") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Guid") + .IsRequired() + .HasMaxLength(45) + .HasColumnType("nvarchar(45)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsTestUser") + .HasColumnType("bit"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Password") + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordIterations") + .HasColumnType("int"); + + b.Property("PasswordPepper") + .HasColumnType("nvarchar(max)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("UpdateTime") + .HasColumnType("datetime2"); + + b.Property("UpdateUserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.HasIndex(new[] { "Email" }, "IX_Email"); + + b.HasIndex(new[] { "IsDeleted", "Guid" }, "IX_IsDeleted_Guid") + .HasFilter("[IsDeleted] = 0"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModule", b => + { + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionModule", "PermissionModule") + .WithMany() + .HasForeignKey("PermissionModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystem", "PermissionSystem") + .WithMany() + .HasForeignKey("PermissionSystemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PermissionModule"); + + b.Navigation("PermissionSystem"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModuleOperation", b => + { + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionOperation", "PermissionOperation") + .WithMany() + .HasForeignKey("PermissionOperationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModule", "PermissionSystemModule") + .WithMany() + .HasForeignKey("PermissionSystemModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PermissionOperation"); + + b.Navigation("PermissionSystemModule"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.RolePermissionSystemModuleOperation", b => + { + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.PermissionSystemModuleOperation", "PermissionSystemModuleOperation") + .WithMany() + .HasForeignKey("PermissionSystemModuleOperationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PermissionSystemModuleOperation"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.User", b => + { + b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role") + .WithMany() + .HasForeignKey("RoleId"); + + b.Navigation("Role"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs new file mode 100644 index 0000000..3fd90e8 --- /dev/null +++ b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs @@ -0,0 +1,109 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MainProject.Migrations +{ + /// + public partial class AlterTableUsersForPasswordEncryption : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_Roles_RoleId", + table: "Users"); + + migrationBuilder.DropColumn( + name: "PasswordHash", + table: "Users"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "Users", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "int"); + + migrationBuilder.AlterColumn( + name: "Password", + table: "Users", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AddColumn( + name: "PasswordIterations", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PasswordPepper", + table: "Users", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Users_Roles_RoleId", + table: "Users", + column: "RoleId", + principalTable: "Roles", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_Roles_RoleId", + table: "Users"); + + migrationBuilder.DropColumn( + name: "PasswordIterations", + table: "Users"); + + migrationBuilder.DropColumn( + name: "PasswordPepper", + table: "Users"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Password", + table: "Users", + type: "nvarchar(max)", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "PasswordHash", + table: "Users", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddForeignKey( + name: "FK_Users_Roles_RoleId", + table: "Users", + column: "RoleId", + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/MainProject/Migrations/SqlServerContextModelSnapshot.cs b/MainProject/Migrations/SqlServerContextModelSnapshot.cs index d32f3cb..5d71ef6 100644 --- a/MainProject/Migrations/SqlServerContextModelSnapshot.cs +++ b/MainProject/Migrations/SqlServerContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace MainProject.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "9.0.2") + .HasAnnotation("ProductVersion", "9.0.5") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -435,18 +435,19 @@ namespace MainProject.Migrations .HasColumnType("nvarchar(200)"); b.Property("Password") - .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("PasswordHash") - .IsRequired() + b.Property("PasswordIterations") + .HasColumnType("int"); + + b.Property("PasswordPepper") .HasColumnType("nvarchar(max)"); b.Property("PasswordSalt") .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("RoleId") + b.Property("RoleId") .HasColumnType("int"); b.Property("UpdateTime") @@ -528,9 +529,7 @@ namespace MainProject.Migrations { b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role") .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("RoleId"); b.Navigation("Role"); }); diff --git a/MainProject/Services/UserService.cs b/MainProject/Services/UserService.cs index f7e1644..54ecef4 100644 --- a/MainProject/Services/UserService.cs +++ b/MainProject/Services/UserService.cs @@ -43,6 +43,9 @@ public class UserService : BaseService, IUserService private User CreateUserData(CreateUserRequestData data, Role role) { + var salt = _appSettings.EncryptionSettings?.Salt ?? String.Empty; + var pepper = CryptUtils.GeneratePepper(); + var iterations = _appSettings.EncryptionSettings?.Iterations ?? 10; User user = new() { CreationTime = DateTime.UtcNow, @@ -52,10 +55,10 @@ public class UserService : BaseService, IUserService FirstName = data.FirstName, LastName = data.LastName, Email = data.Email, - PasswordSalt = _appSettings.EncryptionSettings?.Salt ?? String.Empty, - PasswordPepper = CryptUtils.GeneratePepper(), - PasswordIterations = _appSettings.EncryptionSettings?.Iterations ?? 10, - Password = "", + PasswordSalt = salt, + PasswordPepper = pepper, + PasswordIterations = iterations, + Password = CryptUtils.GeneratePassword(data.Password, salt, iterations, pepper), Role = role, IsTestUser = false }; diff --git a/MainProject/Utils/PasswordUtils.cs b/MainProject/Utils/PasswordUtils.cs index 8deb1d3..b1cd1fc 100644 --- a/MainProject/Utils/PasswordUtils.cs +++ b/MainProject/Utils/PasswordUtils.cs @@ -7,10 +7,9 @@ using BasicDotnetTemplate.MainProject.Enum; using BasicDotnetTemplate.MainProject.Models.Settings; namespace BasicDotnetTemplate.MainProject.Utils; -public partial class PasswordUtils -{ - protected PasswordUtils() { } +public static partial class PasswordUtils +{ private const int MIN_LENGTH = 8; private const int MIN_UPPER = 2; private const int MIN_LOWER = 2; diff --git a/MainProject/appsettings.json b/MainProject/appsettings.json index dde36ef..274bdd2 100644 --- a/MainProject/appsettings.json +++ b/MainProject/appsettings.json @@ -36,7 +36,7 @@ }, "EncryptionSettings": { "SaltKey": "S7VIidfXQf1tOQYX", - "Salt": "", + "Salt": "u5CZAwq9vLGysC", "Iterations": 10 }, "PermissionsSettings": { From 8986e3d77e95500108eaafaceb95bf4961f7f798 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 21:11:35 +0200 Subject: [PATCH 07/20] Minor fixes --- MainProject.Tests/Services/UserService_Tests.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/MainProject.Tests/Services/UserService_Tests.cs b/MainProject.Tests/Services/UserService_Tests.cs index 1d4c75f..80f5ae1 100644 --- a/MainProject.Tests/Services/UserService_Tests.cs +++ b/MainProject.Tests/Services/UserService_Tests.cs @@ -84,11 +84,11 @@ public class UserService_Tests var user = await _userService.CreateUserAsync(data, role); Assert.IsInstanceOfType(user, typeof(User)); Assert.IsNotNull(user); - Assert.IsTrue(expectedUser.FirstName == user.FirstName); - Assert.IsTrue(expectedUser.LastName == user.LastName); - Assert.IsTrue(expectedUser.Email == user.Email); - Assert.IsTrue(expectedUser.Role?.Name == user.Role?.Name); - Assert.IsTrue(user.PasswordIterations == 10); + Assert.AreEqual(expectedUser.FirstName, user.FirstName); + Assert.AreEqual(expectedUser.LastName, user.LastName); + Assert.AreEqual(expectedUser.Email, user.Email); + Assert.AreEqual(expectedUser.Role?.Name, user.Role?.Name); + Assert.AreEqual(10, user.PasswordIterations); Assert.IsNotNull(expectedUser.PasswordSalt); Assert.IsNotNull(expectedUser.PasswordPepper); Assert.IsNotNull(expectedUser.Password); @@ -107,10 +107,9 @@ public class UserService_Tests { try { - var testString = "test"; if (_userService != null) { - var user = await _userService.GetUserByUsernameAndPassword(testString, testString); + var user = await _userService.GetUserByUsernameAndPassword(_user.Email, "WrongPassword"); Assert.IsTrue(user == null); } else From e1a249c07a94ef7da088de6224f1c6f012c7d439 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Tue, 17 Jun 2025 23:08:21 +0200 Subject: [PATCH 08/20] Adding crud operations for users --- MainProject.Tests/MainProject.Tests.csproj | 6 +- .../Services/UserService_Tests.cs | 188 +++++++++++++++++- MainProject/Controllers/RoleController.cs | 2 +- MainProject/Controllers/UserController.cs | 180 +++++++++++++++++ MainProject/MainProject.csproj | 34 ++-- .../Api/Data/User/CreateUserRequestData.cs | 4 +- .../Api/Data/User/UpdateUserRequestData.cs | 12 ++ .../Api/Request/User/UpdateUserRequest.cs | 14 ++ MainProject/Services/UserService.cs | 81 ++++++++ 9 files changed, 493 insertions(+), 28 deletions(-) create mode 100644 MainProject/Models/Api/Data/User/UpdateUserRequestData.cs create mode 100644 MainProject/Models/Api/Request/User/UpdateUserRequest.cs diff --git a/MainProject.Tests/MainProject.Tests.csproj b/MainProject.Tests/MainProject.Tests.csproj index b083669..975aa5a 100644 --- a/MainProject.Tests/MainProject.Tests.csproj +++ b/MainProject.Tests/MainProject.Tests.csproj @@ -14,11 +14,11 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + - - + + diff --git a/MainProject.Tests/Services/UserService_Tests.cs b/MainProject.Tests/Services/UserService_Tests.cs index 80f5ae1..ce5f670 100644 --- a/MainProject.Tests/Services/UserService_Tests.cs +++ b/MainProject.Tests/Services/UserService_Tests.cs @@ -110,7 +110,7 @@ public class UserService_Tests if (_userService != null) { var user = await _userService.GetUserByUsernameAndPassword(_user.Email, "WrongPassword"); - Assert.IsTrue(user == null); + Assert.IsNull(user); } else { @@ -133,7 +133,7 @@ public class UserService_Tests if (_userService != null) { var user = await _userService.GetUserByUsernameAndPassword(_user.Email, password); - Assert.IsTrue(user != null); + Assert.IsNotNull(user); } else { @@ -250,7 +250,7 @@ public class UserService_Tests { var user = await _userService.GetUserByIdAsync(_user.Id); Assert.IsNotNull(user); - Assert.IsTrue(user.Id == _user?.Id); + Assert.AreEqual(user.Id, _user?.Id); } else { @@ -274,7 +274,7 @@ public class UserService_Tests { var user = await _userService.GetUserByGuidAsync(_user.Guid ?? String.Empty); Assert.IsNotNull(user); - Assert.IsTrue(user.Guid == _user?.Guid); + Assert.AreEqual(user.Guid, _user?.Guid); } else { @@ -288,6 +288,186 @@ public class UserService_Tests } } + [TestMethod] + public async Task UpdateUserAsync_Success() + { + try + { + UpdateUserRequestData data = new UpdateUserRequestData() + { + FirstName = "ChangedUserFirstName", + LastName = "ChangedUserLastName" + }; + + if (_userService != null) + { + Assert.IsNotNull(_user); + var user = await _userService.UpdateUserAsync(data, _user!); + Assert.IsInstanceOfType(user, typeof(User)); + Assert.IsNotNull(user); + Assert.AreEqual(data.FirstName, user.FirstName); + Assert.AreEqual(data.LastName, user.LastName); + _user = user; + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.InnerException); + Assert.Fail($"An exception was thrown: {ex}"); + } + } + + [TestMethod] + public async Task UpdateUserAsync_Exception() + { + try + { + UpdateUserRequestData data = new UpdateUserRequestData() + { + FirstName = "ChangedUserFirstName", + LastName = "ChangedUserLastName" + }; + + var exceptionUserService = TestUtils.CreateUserServiceException(); + + if (exceptionUserService != null) + { + Assert.IsNotNull(_user); + var user = await exceptionUserService.UpdateUserAsync(data, _user!); + Assert.Fail($"Expected exception instead of response: {user?.Guid}"); + + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Assert.IsInstanceOfType(ex, typeof(Exception)); + } + } + + + [TestMethod] + public async Task UpdateUserPasswordAsync_Success() + { + try + { + if (_userService != null) + { + Assert.IsNotNull(_user); + var oldPassword = _user.Password; + var user = await _userService.UpdateUserPasswordAsync(_user!, "this-is-a-new-password"); + Assert.IsInstanceOfType(user, typeof(User)); + Assert.IsNotNull(user); + Assert.IsTrue(user.Password != oldPassword); + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.InnerException); + Assert.Fail($"An exception was thrown: {ex}"); + } + } + + [TestMethod] + public async Task UpdateUserPasswordAsync_Exception() + { + try + { + var exceptionUserService = TestUtils.CreateUserServiceException(); + + if (exceptionUserService != null) + { + Assert.IsNotNull(_user); + var user = await exceptionUserService.UpdateUserPasswordAsync(_user!, "this-is-a-new-password"); + Assert.Fail($"Expected exception instead of response: {user?.Guid}"); + + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Assert.IsInstanceOfType(ex, typeof(Exception)); + } + } + + [TestMethod] + public async Task UpdateUserRoleAsync_Success() + { + try + { + if (_userService != null) + { + Assert.IsNotNull(_user); + Role role = new() + { + Name = "NewRole", + IsNotEditable = false, + Guid = Guid.NewGuid().ToString() + }; + + var oldRole = _user.Role; + var user = await _userService.UpdateUserRoleAsync(_user!, role); + Assert.IsInstanceOfType(user, typeof(User)); + Assert.IsNotNull(user); + Assert.IsTrue(user.Role?.Id != oldRole?.Id); + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.InnerException); + Assert.Fail($"An exception was thrown: {ex}"); + } + } + + [TestMethod] + public async Task UpdateUserRoleAsync_Exception() + { + try + { + var exceptionUserService = TestUtils.CreateUserServiceException(); + + if (exceptionUserService != null) + { + Assert.IsNotNull(_user); + Role role = new() + { + Name = "NewRole", + IsNotEditable = false, + Guid = Guid.NewGuid().ToString() + }; + var user = await exceptionUserService.UpdateUserRoleAsync(_user!, role); + Assert.Fail($"Expected exception instead of response: {user?.Guid}"); + + } + else + { + Assert.Fail($"UserService is null"); + } + } + catch (Exception ex) + { + Assert.IsInstanceOfType(ex, typeof(Exception)); + } + } + [TestMethod] public async Task DeleteUser() { diff --git a/MainProject/Controllers/RoleController.cs b/MainProject/Controllers/RoleController.cs index 5b369a1..ef276d1 100644 --- a/MainProject/Controllers/RoleController.cs +++ b/MainProject/Controllers/RoleController.cs @@ -206,7 +206,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return NotFound(); } - await this._roleService.DeleteRoleAsync(role); + await this._roleService.DeleteRoleAsync(role); return Success(String.Empty); } diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index cd9502b..0822cf5 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -128,7 +128,187 @@ namespace BasicDotnetTemplate.MainProject.Controllers } + [JwtAuthorization()] + [HttpPut("update/{guid}")] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType>(StatusCodes.Status400BadRequest)] + [ProducesResponseType>(StatusCodes.Status500InternalServerError)] + public async Task UpdateUserAsync([FromBody] UpdateUserRequest request, string guid) + { + try + { + if (!ModelState.IsValid) + { + return BadRequest(_requestNotWellFormed); + } + if (request == null || request.Data == null || + String.IsNullOrEmpty(request.Data.FirstName) || + String.IsNullOrEmpty(request.Data.LastName) + ) + { + return BadRequest(_requestNotWellFormed); + } + var user = await this._userService.GetUserByGuidAsync(guid); + if(user == null) + { + return NotFound(); + } + + user = await this._userService.UpdateUserAsync(request.Data, user); + + var userDto = _mapper?.Map(user); + + return Success(String.Empty, userDto); + + } + catch (Exception exception) + { + var message = this._somethingWentWrong; + if (!String.IsNullOrEmpty(exception.Message)) + { + message += $". {exception.Message}"; + } + return InternalServerError(message); + } + + } + + [JwtAuthorization()] + [HttpPut("update/{guid}/password")] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType>(StatusCodes.Status400BadRequest)] + [ProducesResponseType>(StatusCodes.Status500InternalServerError)] + public async Task UpdateUserPasswordAsync(string guid, string newPassword) + { + try + { + if (!ModelState.IsValid) + { + return BadRequest(_requestNotWellFormed); + } + + if (String.IsNullOrEmpty(newPassword)) + { + return BadRequest(_requestNotWellFormed); + } + + var user = await this._userService.GetUserByGuidAsync(guid); + if(user == null) + { + return NotFound(); + } + + user = await this._userService.UpdateUserPasswordAsync(user, newPassword); + + var userDto = _mapper?.Map(user); + + return Success(String.Empty, userDto); + + } + catch (Exception exception) + { + var message = this._somethingWentWrong; + if (!String.IsNullOrEmpty(exception.Message)) + { + message += $". {exception.Message}"; + } + return InternalServerError(message); + } + + } + + [JwtAuthorization()] + [HttpPut("update/{guid}/role")] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType>(StatusCodes.Status400BadRequest)] + [ProducesResponseType>(StatusCodes.Status500InternalServerError)] + public async Task UpdateUserRoleAsync(string guid, string roleGuid) + { + try + { + if (!ModelState.IsValid) + { + return BadRequest(_requestNotWellFormed); + } + + if (String.IsNullOrEmpty(roleGuid)) + { + return BadRequest(_requestNotWellFormed); + } + + var role = await this._roleService.GetRoleForUser(roleGuid); + if (role == null) + { + return BadRequest("Role not found"); + } + + var user = await this._userService.GetUserByGuidAsync(guid); + if(user == null) + { + return NotFound(); + } + + user = await this._userService.UpdateUserRoleAsync(user, role); + + var userDto = _mapper?.Map(user); + + return Success(String.Empty, userDto); + + } + catch (Exception exception) + { + var message = this._somethingWentWrong; + if (!String.IsNullOrEmpty(exception.Message)) + { + message += $". {exception.Message}"; + } + return InternalServerError(message); + } + + } + + [JwtAuthorization()] + [HttpDelete("{guid}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType>(StatusCodes.Status404NotFound)] + [ProducesResponseType>(StatusCodes.Status400BadRequest)] + [ProducesResponseType>(StatusCodes.Status500InternalServerError)] + public async Task DeleteUserByGuidAsync(string guid) + { + try + { + if (!ModelState.IsValid) + { + return BadRequest(_requestNotWellFormed); + } + + if (String.IsNullOrEmpty(guid)) + { + return BadRequest(_requestNotWellFormed); + } + var user = await this._userService.GetUserByGuidAsync(guid); + + if (user == null || String.IsNullOrEmpty(user.Guid)) + { + return NotFound(); + } + + await this._userService.DeleteUserAsync(user); + + return Success(String.Empty); + } + catch (Exception exception) + { + var message = this._somethingWentWrong; + if (!String.IsNullOrEmpty(exception.Message)) + { + message += $". {exception.Message}"; + } + return InternalServerError(message); + } + + } } } \ No newline at end of file diff --git a/MainProject/MainProject.csproj b/MainProject/MainProject.csproj index 801b05c..3fecdf7 100644 --- a/MainProject/MainProject.csproj +++ b/MainProject/MainProject.csproj @@ -15,21 +15,21 @@ all - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -37,14 +37,14 @@ - - - - - - - - + + + + + + + + diff --git a/MainProject/Models/Api/Data/User/CreateUserRequestData.cs b/MainProject/Models/Api/Data/User/CreateUserRequestData.cs index 2202def..01fb31c 100644 --- a/MainProject/Models/Api/Data/User/CreateUserRequestData.cs +++ b/MainProject/Models/Api/Data/User/CreateUserRequestData.cs @@ -1,9 +1,7 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Data.User; -public class CreateUserRequestData +public class CreateUserRequestData : UpdateUserRequestData { - public string FirstName { get; set; } = String.Empty; - public string LastName { get; set; } = String.Empty; public string Email { get; set; } = String.Empty; public string Password { get; set; } = String.Empty; public string? RoleGuid { get; set; } diff --git a/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs b/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs new file mode 100644 index 0000000..a5772af --- /dev/null +++ b/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs @@ -0,0 +1,12 @@ +namespace BasicDotnetTemplate.MainProject.Models.Api.Data.User; + +public class UpdateUserRequestData +{ + public string FirstName { get; set; } = String.Empty; + public string LastName { get; set; } = String.Empty; + +} + + + + diff --git a/MainProject/Models/Api/Request/User/UpdateUserRequest.cs b/MainProject/Models/Api/Request/User/UpdateUserRequest.cs new file mode 100644 index 0000000..c2bf2df --- /dev/null +++ b/MainProject/Models/Api/Request/User/UpdateUserRequest.cs @@ -0,0 +1,14 @@ +using BasicDotnetTemplate.MainProject.Models.Api.Data.User; + +namespace BasicDotnetTemplate.MainProject.Models.Api.Request.User; + +public class UpdateUserRequest +{ +#nullable enable + public UpdateUserRequestData? Data { get; set; } +#nullable disable +} + + + + diff --git a/MainProject/Services/UserService.cs b/MainProject/Services/UserService.cs index 54ecef4..2f04ce5 100644 --- a/MainProject/Services/UserService.cs +++ b/MainProject/Services/UserService.cs @@ -16,7 +16,10 @@ public interface IUserService Task GetUserByUsernameAndPassword(string email, string password); Task CheckIfEmailIsValid(string email, string? guid = ""); Task CreateUserAsync(CreateUserRequestData data, Role role); + Task UpdateUserAsync(UpdateUserRequestData data, User user); Task DeleteUserAsync(User user); + Task UpdateUserPasswordAsync(User user, string newPassword); + Task UpdateUserRoleAsync(User user, Role newRole); } public class UserService : BaseService, IUserService @@ -134,6 +137,31 @@ public class UserService : BaseService, IUserService return user; } + public async Task UpdateUserAsync(UpdateUserRequestData data, User user) + { + using var transaction = await _sqlServerContext.Database.BeginTransactionAsync(); + + try + { + user.FirstName = data.FirstName ?? user.FirstName; + user.LastName = data.LastName ?? user.LastName; + user.UpdateTime = DateTime.UtcNow; + user.UpdateUserId = this.GetCurrentUserId(); + + _sqlServerContext.Users.Update(user); + await _sqlServerContext.SaveChangesAsync(); + await transaction.CommitAsync(); + } + catch (Exception exception) + { + Logger.Error(exception, $"[UserService][UpdateUserAsync] | {transaction.TransactionId}"); + await transaction.RollbackAsync(); + throw new UpdateException($"An error occurred while updating the user for transaction ID {transaction.TransactionId}.", exception); + } + + return user; + } + public async Task DeleteUserAsync(User user) { bool? deleted = false; @@ -151,6 +179,59 @@ public class UserService : BaseService, IUserService return deleted; } + public async Task UpdateUserPasswordAsync(User user, string newPassword) + { + using var transaction = await _sqlServerContext.Database.BeginTransactionAsync(); + try + { + var salt = _appSettings.EncryptionSettings?.Salt ?? String.Empty; + var pepper = CryptUtils.GeneratePepper(); + var iterations = _appSettings.EncryptionSettings?.Iterations ?? 10; + + user.PasswordSalt = salt; + user.PasswordPepper = pepper; + user.PasswordIterations = iterations; + user.Password = CryptUtils.GeneratePassword(newPassword, salt, iterations, pepper); + user.UpdateTime = DateTime.UtcNow; + user.UpdateUserId = this.GetCurrentUserId(); + + _sqlServerContext.Users.Update(user); + await _sqlServerContext.SaveChangesAsync(); + await transaction.CommitAsync(); + } + catch (Exception exception) + { + Logger.Error(exception, $"[UserService][UpdateUserPasswordAsync] | {transaction.TransactionId}"); + await transaction.RollbackAsync(); + throw new UpdateException($"An error occurred while updating the user for transaction ID {transaction.TransactionId}.", exception); + } + + return user; + } + + public async Task UpdateUserRoleAsync(User user, Role newRole) + { + using var transaction = await _sqlServerContext.Database.BeginTransactionAsync(); + + try + { + user.Role = newRole; + user.UpdateTime = DateTime.UtcNow; + user.UpdateUserId = this.GetCurrentUserId(); + + _sqlServerContext.Users.Update(user); + await _sqlServerContext.SaveChangesAsync(); + await transaction.CommitAsync(); + } + catch (Exception exception) + { + Logger.Error(exception, $"[UserService][UpdateUserRoleAsync] | {transaction.TransactionId}"); + await transaction.RollbackAsync(); + throw new UpdateException($"An error occurred while updating the user for transaction ID {transaction.TransactionId}.", exception); + } + + return user; + } } From 8bc50f81355492d1d436c430ce3f9f34bcad2187 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 00:30:16 +0200 Subject: [PATCH 09/20] Removing duplicated lines - wip --- .../Controllers/AuthController_Tests.cs | 132 ++--- .../Controllers/RoleController_Tests.cs | 556 +++++++++--------- .../Controllers/UserController_Tests.cs | 289 ++++----- .../Services/UserService_Tests.cs | 3 +- MainProject/Controllers/AuthController.cs | 18 +- MainProject/Controllers/BaseController.cs | 1 - MainProject/Controllers/RoleController.cs | 53 +- MainProject/Controllers/UserController.cs | 79 +-- ...alidateModelStateAutomaticallyAttribute.cs | 12 + .../Core/Filters/ValidationActionFilter.cs | 30 + .../Api/Data/Role/CreateRoleRequestData.cs | 5 +- .../Api/Data/User/CreateUserRequestData.cs | 11 +- .../Api/Data/User/UpdateUserRequestData.cs | 11 +- MainProject/Utils/ProgramUtils.cs | 7 +- 14 files changed, 581 insertions(+), 626 deletions(-) create mode 100644 MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs create mode 100644 MainProject/Core/Filters/ValidationActionFilter.cs diff --git a/MainProject.Tests/Controllers/AuthController_Tests.cs b/MainProject.Tests/Controllers/AuthController_Tests.cs index 2b58b55..a6d0a7f 100644 --- a/MainProject.Tests/Controllers/AuthController_Tests.cs +++ b/MainProject.Tests/Controllers/AuthController_Tests.cs @@ -81,41 +81,41 @@ public class AuthController_Tests } } - [TestMethod] - public async Task AuthenticateAsync_AuthenticateRequestDataNull() - { - IConfiguration configuration = TestUtils.CreateConfiguration(); - var authServiceMock = new Mock(); - var controller = new AuthController(configuration, authServiceMock.Object); + // [TestMethod] + // public async Task AuthenticateAsync_AuthenticateRequestDataNull() + // { + // IConfiguration configuration = TestUtils.CreateConfiguration(); + // var authServiceMock = new Mock(); + // var controller = new AuthController(configuration, authServiceMock.Object); - var request = new AuthenticateRequest - { - Data = null - }; - AuthenticatedUser? authenticatedUser = null; - authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); - ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); + // var request = new AuthenticateRequest + // { + // Data = null + // }; + // AuthenticatedUser? authenticatedUser = null; + // authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); + // ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task AuthenticateAsync_NotFound() @@ -148,44 +148,44 @@ public class AuthController_Tests } } - [TestMethod] - public async Task AuthenticateAsync_ModelInvalid() - { - IConfiguration configuration = TestUtils.CreateConfiguration(); - var authServiceMock = new Mock(); - var controller = new AuthController(configuration, authServiceMock.Object); + // [TestMethod] + // public async Task AuthenticateAsync_ModelInvalid() + // { + // IConfiguration configuration = TestUtils.CreateConfiguration(); + // var authServiceMock = new Mock(); + // var controller = new AuthController(configuration, authServiceMock.Object); - var request = new AuthenticateRequest - { - Data = null - }; - AuthenticatedUser? authenticatedUser = null; - authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); - controller.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); + // var request = new AuthenticateRequest + // { + // Data = null + // }; + // AuthenticatedUser? authenticatedUser = null; + // authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); + // controller.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task AuthenticateAsync_Exception() diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index 5fcd784..986e98b 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -89,40 +89,40 @@ public class RoleController_Tests } } - [TestMethod] - public async Task GetRoleByGuidAsync_GuidIsEmpty() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task GetRoleByGuidAsync_GuidIsEmpty() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - var guid = String.Empty; - DatabaseSqlServer.Role? role = null; + // var guid = String.Empty; + // DatabaseSqlServer.Role? role = null; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task GetRoleByGuidAsync_NotFound() @@ -149,42 +149,42 @@ public class RoleController_Tests } } - [TestMethod] - public async Task GetRoleByGuidAsync_ModelInvalid() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task GetRoleByGuidAsync_ModelInvalid() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - var guid = Guid.NewGuid().ToString(); - DatabaseSqlServer.Role? role = null; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - _roleController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); + // var guid = Guid.NewGuid().ToString(); + // DatabaseSqlServer.Role? role = null; + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // _roleController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task GetRoleByGuidAsync_Exception() @@ -316,49 +316,49 @@ public class RoleController_Tests } } - [TestMethod] - public async Task CreateRoleAsync_CreateRoleRequestDataNull() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task CreateRoleAsync_CreateRoleRequestDataNull() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - CreateRoleRequest request = new CreateRoleRequest() - { - Data = null - }; + // CreateRoleRequest request = new CreateRoleRequest() + // { + // Data = null + // }; - _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _roleServiceMock?.Setup(s => s.CreateRoleAsync( - It.IsAny() - )).ReturnsAsync(role); + // _roleServiceMock?.Setup(s => s.CreateRoleAsync( + // It.IsAny() + // )).ReturnsAsync(role); - ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); + // ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task CreateRoleAsync_NotCreated() @@ -410,55 +410,55 @@ public class RoleController_Tests } } - [TestMethod] - public async Task CreateRoleAsync_ModelInvalid() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task CreateRoleAsync_ModelInvalid() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - CreateRoleRequest request = new CreateRoleRequest() - { - Data = new CreateRoleRequestData() - { - Name = "RoleTest", - IsNotEditable = true - } - }; + // CreateRoleRequest request = new CreateRoleRequest() + // { + // Data = new CreateRoleRequestData() + // { + // Name = "RoleTest", + // IsNotEditable = true + // } + // }; - _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _roleServiceMock?.Setup(s => s.CreateRoleAsync( - It.IsAny() - )).ReturnsAsync(role); - _roleController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); + // _roleServiceMock?.Setup(s => s.CreateRoleAsync( + // It.IsAny() + // )).ReturnsAsync(role); + // _roleController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task CreateRoleAsync_Exception() @@ -539,40 +539,40 @@ public class RoleController_Tests } } - [TestMethod] - public async Task DeleteRoleByGuidAsync_GuidIsEmpty() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task DeleteRoleByGuidAsync_GuidIsEmpty() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - var guid = String.Empty; - DatabaseSqlServer.Role? role = null; + // var guid = String.Empty; + // DatabaseSqlServer.Role? role = null; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task DeleteRoleByGuidAsync_NotFound() @@ -599,42 +599,42 @@ public class RoleController_Tests } } - [TestMethod] - public async Task DeleteRoleByGuidAsync_ModelInvalid() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task DeleteRoleByGuidAsync_ModelInvalid() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - var guid = Guid.NewGuid().ToString(); - DatabaseSqlServer.Role? role = null; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - _roleController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); + // var guid = Guid.NewGuid().ToString(); + // DatabaseSqlServer.Role? role = null; + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // _roleController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task DeleteRoleByGuidAsync_Exception() @@ -851,95 +851,95 @@ public class RoleController_Tests } } - [TestMethod] - public async Task UpdateRoleAsync_CreateRoleRequestDataNull() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task UpdateRoleAsync_CreateRoleRequestDataNull() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - CreateRoleRequest request = new CreateRoleRequest() - { - Data = null - }; + // CreateRoleRequest request = new CreateRoleRequest() + // { + // Data = null + // }; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); - ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); + // ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } - [TestMethod] - public async Task UpdateRoleAsync_ModelInvalid() - { - if (_roleController == null) - { - Assert.Fail($"_roleController is null"); - } + // [TestMethod] + // public async Task UpdateRoleAsync_ModelInvalid() + // { + // if (_roleController == null) + // { + // Assert.Fail($"_roleController is null"); + // } - DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - CreateRoleRequest request = new CreateRoleRequest() - { - Data = new CreateRoleRequestData() - { - Name = "RoleTest", - IsNotEditable = true - } - }; + // CreateRoleRequest request = new CreateRoleRequest() + // { + // Data = new CreateRoleRequestData() + // { + // Name = "RoleTest", + // IsNotEditable = true + // } + // }; - _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); - _roleController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); + // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); + // _roleController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task UpdateRoleAsync_Exception() diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index cc94f2b..5966da9 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -99,40 +99,40 @@ public class UserController_Tests } } - [TestMethod] - public async Task GetUserByGuidAsync_GuidIsEmpty() - { - if (_userController == null) - { - Assert.Fail($"_userController is null"); - } + // [TestMethod] + // public async Task GetUserByGuidAsync_GuidIsEmpty() + // { + // if (_userController == null) + // { + // Assert.Fail($"_userController is null"); + // } - var guid = String.Empty; - DatabaseSqlServer.User? user = null; + // var guid = String.Empty; + // DatabaseSqlServer.User? user = null; - _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); - ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); + // _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + // ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task GetUserByGuidAsync_NotFound() @@ -159,42 +159,42 @@ public class UserController_Tests } } - [TestMethod] - public async Task GetUserByGuidAsync_ModelInvalid() - { - if (_userController == null) - { - Assert.Fail($"_userController is null"); - } + // [TestMethod] + // public async Task GetUserByGuidAsync_ModelInvalid() + // { + // if (_userController == null) + // { + // Assert.Fail($"_userController is null"); + // } - var guid = Guid.NewGuid().ToString(); - DatabaseSqlServer.User? user = null; - _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); - _userController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); + // var guid = Guid.NewGuid().ToString(); + // DatabaseSqlServer.User? user = null; + // _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + // _userController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task GetUserByGuidAsync_Exception() @@ -381,50 +381,50 @@ public class UserController_Tests } } - [TestMethod] - public async Task CreateUserAsync_CreateUserRequestDataNull() - { - if (_userController == null) - { - Assert.Fail($"_userController is null"); - } + // [TestMethod] + // public async Task CreateUserAsync_CreateUserRequestDataNull() + // { + // if (_userController == null) + // { + // Assert.Fail($"_userController is null"); + // } - DatabaseSqlServer.User user = ModelsInit.CreateUser(); + // DatabaseSqlServer.User user = ModelsInit.CreateUser(); - CreateUserRequest request = new CreateUserRequest() - { - Data = null - }; + // CreateUserRequest request = new CreateUserRequest() + // { + // Data = null + // }; - _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _userServiceMock?.Setup(s => s.CreateUserAsync( - It.IsAny(), - It.IsAny() - )).ReturnsAsync(user); + // _userServiceMock?.Setup(s => s.CreateUserAsync( + // It.IsAny(), + // It.IsAny() + // )).ReturnsAsync(user); - ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); + // ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response value is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response value is null"); + // } + // } [TestMethod] public async Task CreateUserAsync_NotCreated() @@ -481,58 +481,59 @@ public class UserController_Tests } } - [TestMethod] - public async Task CreateUserAsync_ModelInvalid() - { - if (_userController == null) - { - Assert.Fail($"_userController is null"); - } + // [TestMethod] + // public async Task CreateUserAsync_ModelInvalid() + // { + // if (_userController == null) + // { + // Assert.Fail($"_userController is null"); + // } - DatabaseSqlServer.User user = ModelsInit.CreateUser(); + // DatabaseSqlServer.User user = ModelsInit.CreateUser(); - CreateUserRequest request = new CreateUserRequest() - { - Data = new CreateUserRequestData() - { - FirstName = user.FirstName, - LastName = user.LastName, - Email = user.Email, - Password = user.Password - } - }; + // CreateUserRequest request = new CreateUserRequest() + // { + // Data = new CreateUserRequestData() + // { + // FirstName = user.FirstName, + // LastName = user.LastName, + // Email = user.Email, + // Password = user.Password + // } + // }; - _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); + // _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - _userServiceMock?.Setup(s => s.CreateUserAsync( - It.IsAny(), - It.IsAny() - )).ReturnsAsync(user); - _userController.ModelState.AddModelError("Data", "Invalid data"); - ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); + // _userServiceMock?.Setup(s => s.CreateUserAsync( + // It.IsAny(), + // It.IsAny() + // )).ReturnsAsync(user); + // _userController.ModelState.AddModelError("Data", "Invalid data"); + // ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); - Assert.IsInstanceOfType(response, typeof(ObjectResult)); + // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - if (response != null && response.Value != null) - { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // if (response != null && response.Value != null) + // { + // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); - var result = (BaseResponse)response.Value; - if (result != null) - { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Request is not well formed"); - } - else - { - Assert.Fail($"Result value is null"); - } - } - else - { - Assert.Fail($"Response is null"); - } - } + // var result = (BaseResponse)response.Value; + // if (result != null) + // { + // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Console.WriteLine(JsonConvert.SerializeObject(result)); + // Assert.IsTrue(result.Message == "Request is not well formed"); + // } + // else + // { + // Assert.Fail($"Result value is null"); + // } + // } + // else + // { + // Assert.Fail($"Response is null"); + // } + // } [TestMethod] public async Task CreateUserAsync_Exception() diff --git a/MainProject.Tests/Services/UserService_Tests.cs b/MainProject.Tests/Services/UserService_Tests.cs index ce5f670..a68ec55 100644 --- a/MainProject.Tests/Services/UserService_Tests.cs +++ b/MainProject.Tests/Services/UserService_Tests.cs @@ -158,7 +158,8 @@ public class UserService_Tests { FirstName = expectedUser.FirstName ?? String.Empty, LastName = expectedUser.LastName ?? String.Empty, - Email = expectedUser.Email ?? String.Empty + Email = expectedUser.Email ?? String.Empty, + Password = expectedUser.Password ?? String.Empty }; Role role = new() diff --git a/MainProject/Controllers/AuthController.cs b/MainProject/Controllers/AuthController.cs index 6d9cb6f..9011ee8 100644 --- a/MainProject/Controllers/AuthController.cs +++ b/MainProject/Controllers/AuthController.cs @@ -6,6 +6,7 @@ using BasicDotnetTemplate.MainProject.Models.Api.Request.Auth; using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; using BasicDotnetTemplate.MainProject.Services; +using BasicDotnetTemplate.MainProject.Core.Filters; namespace BasicDotnetTemplate.MainProject.Controllers { @@ -21,29 +22,16 @@ namespace BasicDotnetTemplate.MainProject.Controllers this._authService = authService; } + [ModelStateValidationHandledByFilterAttribute] [HttpPost("authenticate")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status404NotFound)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] - public async Task AuthenticateAsync([FromBody] AuthenticateRequest request) + public async Task AuthenticateAsync([FromBody] AuthenticateRequest request) //NOSONAR { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if ( - request == null || - request.Data == null || - String.IsNullOrEmpty(request.Data.Email) || - String.IsNullOrEmpty(request.Data.Password) - ) - { - return BadRequest(_requestNotWellFormed); - } var data = await this._authService.AuthenticateAsync(request.Data); if (data == null) diff --git a/MainProject/Controllers/BaseController.cs b/MainProject/Controllers/BaseController.cs index ec2f51b..45c8e75 100644 --- a/MainProject/Controllers/BaseController.cs +++ b/MainProject/Controllers/BaseController.cs @@ -12,7 +12,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers protected readonly IMapper? _mapper; protected readonly IConfiguration _configuration; protected readonly AppSettings _appSettings; - protected readonly string _requestNotWellFormed = "Request is not well formed"; protected readonly string _somethingWentWrong = "Something went wrong"; protected BaseController( diff --git a/MainProject/Controllers/RoleController.cs b/MainProject/Controllers/RoleController.cs index ef276d1..966f168 100644 --- a/MainProject/Controllers/RoleController.cs +++ b/MainProject/Controllers/RoleController.cs @@ -7,6 +7,7 @@ using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response.Role; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using BasicDotnetTemplate.MainProject.Models.Api.Common.Role; +using BasicDotnetTemplate.MainProject.Core.Filters; namespace BasicDotnetTemplate.MainProject.Controllers { @@ -23,6 +24,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpGet("get/{guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status404NotFound)] @@ -32,15 +34,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(guid)) - { - return BadRequest(_requestNotWellFormed); - } var role = await this._roleService.GetRoleByGuidAsync(guid); if (role == null || String.IsNullOrEmpty(role.Guid)) @@ -65,25 +58,15 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPost("create")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] - public async Task CreateRoleAsync([FromBody] CreateRoleRequest request) + public async Task CreateRoleAsync([FromBody] CreateRoleRequest request) //NOSONAR { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (request == null || request.Data == null || String.IsNullOrEmpty(request.Data.Name) - ) - { - return BadRequest(_requestNotWellFormed); - } - if (await this._roleService.CheckIfNameIsValid(request.Data.Name)) { var role = await this._roleService.CreateRoleAsync(request.Data); @@ -116,29 +99,15 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] - public async Task UpdateRoleAsync([FromBody] CreateRoleRequest request, string guid) + public async Task UpdateRoleAsync([FromBody] CreateRoleRequest request, string guid) //NOSONAR { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if ( - request == null || - request.Data == null || - String.IsNullOrEmpty(request.Data.Name) || - String.IsNullOrEmpty(guid) - ) - { - return BadRequest(_requestNotWellFormed); - } - var role = await this._roleService.GetRoleByGuidAsync(guid); if (role == null || String.IsNullOrEmpty(role.Guid)) @@ -181,6 +150,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpDelete("{guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status404NotFound)] @@ -190,15 +160,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(guid)) - { - return BadRequest(_requestNotWellFormed); - } var role = await this._roleService.GetRoleByGuidAsync(guid); if (role == null || String.IsNullOrEmpty(role.Guid)) diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index 0822cf5..d27e32e 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -7,6 +7,7 @@ using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response.User; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using BasicDotnetTemplate.MainProject.Models.Api.Common.User; +using BasicDotnetTemplate.MainProject.Core.Filters; namespace BasicDotnetTemplate.MainProject.Controllers { @@ -24,8 +25,10 @@ namespace BasicDotnetTemplate.MainProject.Controllers this._userService = userService; this._roleService = roleService; } + [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpGet("get/{guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status404NotFound)] @@ -35,15 +38,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(guid)) - { - return BadRequest(_requestNotWellFormed); - } var user = await this._userService.GetUserByGuidAsync(guid); if (user == null || String.IsNullOrEmpty(user.Guid)) @@ -67,30 +61,16 @@ namespace BasicDotnetTemplate.MainProject.Controllers } - [JwtAuthorization()] + // [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPost("create")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] - public async Task CreateUserAsync([FromBody] CreateUserRequest request) + public async Task CreateUserAsync([FromBody] CreateUserRequest request) //NOSONAR { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (request == null || request.Data == null || - String.IsNullOrEmpty(request.Data.FirstName) || - String.IsNullOrEmpty(request.Data.LastName) || - String.IsNullOrEmpty(request.Data.Email) || - String.IsNullOrEmpty(request.Data.Password) - ) - { - return BadRequest(_requestNotWellFormed); - } - if (await this._userService.CheckIfEmailIsValid(request.Data.Email)) { var role = await this._roleService.GetRoleForUser(request.Data.RoleGuid); @@ -129,26 +109,15 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] - public async Task UpdateUserAsync([FromBody] UpdateUserRequest request, string guid) + public async Task UpdateUserAsync([FromBody] UpdateUserRequest request, string guid) //NOSONAR { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (request == null || request.Data == null || - String.IsNullOrEmpty(request.Data.FirstName) || - String.IsNullOrEmpty(request.Data.LastName) - ) - { - return BadRequest(_requestNotWellFormed); - } var user = await this._userService.GetUserByGuidAsync(guid); if(user == null) { @@ -175,6 +144,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}/password")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] @@ -183,16 +153,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(newPassword)) - { - return BadRequest(_requestNotWellFormed); - } - var user = await this._userService.GetUserByGuidAsync(guid); if(user == null) { @@ -219,6 +179,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}/role")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] @@ -227,16 +188,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(roleGuid)) - { - return BadRequest(_requestNotWellFormed); - } - var role = await this._roleService.GetRoleForUser(roleGuid); if (role == null) { @@ -269,6 +220,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } [JwtAuthorization()] + [ModelStateValidationHandledByFilterAttribute] [HttpDelete("{guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status404NotFound)] @@ -278,15 +230,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (!ModelState.IsValid) - { - return BadRequest(_requestNotWellFormed); - } - - if (String.IsNullOrEmpty(guid)) - { - return BadRequest(_requestNotWellFormed); - } var user = await this._userService.GetUserByGuidAsync(guid); if (user == null || String.IsNullOrEmpty(user.Guid)) diff --git a/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs b/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs new file mode 100644 index 0000000..72c8d08 --- /dev/null +++ b/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace BasicDotnetTemplate.MainProject.Core.Attributes +{ + /// + /// Indicates that ModelState validation is handled automatically by an Action Filter. + /// Used to suppress SonarCloud warnings about missing ModelState.IsValid checks. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class ModelStateValidationHandledByFilterAttribute : Attribute + { } +} \ No newline at end of file diff --git a/MainProject/Core/Filters/ValidationActionFilter.cs b/MainProject/Core/Filters/ValidationActionFilter.cs new file mode 100644 index 0000000..16f942a --- /dev/null +++ b/MainProject/Core/Filters/ValidationActionFilter.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System.Threading.Tasks; + +namespace BasicDotnetTemplate.MainProject.Core.Filters +{ + public class ValidationActionFilter : IAsyncActionFilter + { + private readonly string _requestNotWellFormedMessage = "Request is not well formed"; + + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + if (!context.ModelState.IsValid) + { + context.Result = new BadRequestObjectResult(new { message = _requestNotWellFormedMessage, errors = context.ModelState }); + return; + } + + var requestBody = context.ActionArguments.Values.FirstOrDefault(arg => arg != null && !arg.GetType().IsPrimitive && !(arg is string)); + + if (requestBody == null) + { + context.Result = new BadRequestObjectResult(new { message = _requestNotWellFormedMessage }); + return; + } + + await next(); + } + } +} \ No newline at end of file diff --git a/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs b/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs index 6831cc0..9cff830 100644 --- a/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs +++ b/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs @@ -1,8 +1,11 @@ +using System.ComponentModel.DataAnnotations; + namespace BasicDotnetTemplate.MainProject.Models.Api.Data.Role; public class CreateRoleRequestData { - public string Name { get; set; } = String.Empty; + [Required(ErrorMessage = "Name is required")] + public required string Name { get; set; } public required bool IsNotEditable { get; set; } } \ No newline at end of file diff --git a/MainProject/Models/Api/Data/User/CreateUserRequestData.cs b/MainProject/Models/Api/Data/User/CreateUserRequestData.cs index 01fb31c..17971c2 100644 --- a/MainProject/Models/Api/Data/User/CreateUserRequestData.cs +++ b/MainProject/Models/Api/Data/User/CreateUserRequestData.cs @@ -1,9 +1,16 @@ +using System.ComponentModel.DataAnnotations; + namespace BasicDotnetTemplate.MainProject.Models.Api.Data.User; public class CreateUserRequestData : UpdateUserRequestData { - public string Email { get; set; } = String.Empty; - public string Password { get; set; } = String.Empty; + [Required(ErrorMessage = "Email is required")] + [StringLength(200, ErrorMessage = "Email's maxLength: 200")] + public required string Email { get; set; } + + [Required(ErrorMessage = "Password is required")] + public required string Password { get; set; } + public string? RoleGuid { get; set; } } diff --git a/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs b/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs index a5772af..aea9cd3 100644 --- a/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs +++ b/MainProject/Models/Api/Data/User/UpdateUserRequestData.cs @@ -1,9 +1,16 @@ +using System.ComponentModel.DataAnnotations; + namespace BasicDotnetTemplate.MainProject.Models.Api.Data.User; public class UpdateUserRequestData { - public string FirstName { get; set; } = String.Empty; - public string LastName { get; set; } = String.Empty; + [Required(ErrorMessage = "FirstName is required")] + [StringLength(200, ErrorMessage = "FirstName's maxLength: 200")] + public required string FirstName { get; set; } + + [Required(ErrorMessage = "LastName is required")] + [StringLength(200, ErrorMessage = "LastName's maxLength: 200")] + public required string LastName { get; set; } } diff --git a/MainProject/Utils/ProgramUtils.cs b/MainProject/Utils/ProgramUtils.cs index eaa8c37..0ab8959 100644 --- a/MainProject/Utils/ProgramUtils.cs +++ b/MainProject/Utils/ProgramUtils.cs @@ -8,7 +8,7 @@ using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Services; using BasicDotnetTemplate.MainProject.Models.Api.Data.Role; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; - +using BasicDotnetTemplate.MainProject.Core.Filters; namespace BasicDotnetTemplate.MainProject.Utils; @@ -140,7 +140,10 @@ public static class ProgramUtils builder.Services.AddAuthentication(); builder.Services.AddAuthorization(); - builder.Services.AddControllers(); + builder.Services.AddControllers(options => + { + options.Filters.Add(); + }); builder.Services.AddEndpointsApiExplorer(); Logger.Info("[ProgramUtils][AddServices] Done services"); From 1fc8e6cc1cc68ab70a33ebf677355a07612bbec7 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 00:53:52 +0200 Subject: [PATCH 10/20] Fixing sonarcloud issues --- .../Controllers/AuthController_Tests.cs | 12 ++-- .../Controllers/RoleController_Tests.cs | 58 +++++++++---------- .../Controllers/UserController_Tests.cs | 28 ++++----- MainProject/Controllers/UserController.cs | 2 +- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/MainProject.Tests/Controllers/AuthController_Tests.cs b/MainProject.Tests/Controllers/AuthController_Tests.cs index a6d0a7f..cf06461 100644 --- a/MainProject.Tests/Controllers/AuthController_Tests.cs +++ b/MainProject.Tests/Controllers/AuthController_Tests.cs @@ -61,7 +61,7 @@ public class AuthController_Tests ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -98,7 +98,7 @@ public class AuthController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -140,7 +140,7 @@ public class AuthController_Tests if (response != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound); + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); } else { @@ -168,7 +168,7 @@ public class AuthController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -207,13 +207,13 @@ public class AuthController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index 986e98b..30320a0 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -70,7 +70,7 @@ public class RoleController_Tests ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -105,7 +105,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -141,7 +141,7 @@ public class RoleController_Tests if (response != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound); + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); } else { @@ -167,7 +167,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -202,13 +202,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { @@ -255,7 +255,7 @@ public class RoleController_Tests ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -297,13 +297,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Invalid name"); + Assert.AreEqual("Invalid name", result.Message ); } else { @@ -341,7 +341,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -391,7 +391,7 @@ public class RoleController_Tests ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -441,7 +441,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -494,13 +494,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { @@ -531,7 +531,7 @@ public class RoleController_Tests ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); } else { @@ -555,7 +555,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -591,7 +591,7 @@ public class RoleController_Tests if (response != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound); + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); } else { @@ -617,7 +617,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -652,13 +652,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { @@ -708,7 +708,7 @@ public class RoleController_Tests ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -752,7 +752,7 @@ public class RoleController_Tests if (response != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound); + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); } else { @@ -786,13 +786,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Invalid name"); + Assert.AreEqual("Invalid name", result.Message ); } else { @@ -832,7 +832,7 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -874,7 +874,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -922,7 +922,7 @@ public class RoleController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -976,13 +976,13 @@ public class RoleController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 5966da9..3e383c3 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -80,7 +80,7 @@ public class UserController_Tests ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -115,7 +115,7 @@ public class UserController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -151,7 +151,7 @@ public class UserController_Tests if (response != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound); + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); } else { @@ -177,7 +177,7 @@ public class UserController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -212,13 +212,13 @@ public class UserController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { @@ -265,7 +265,7 @@ public class UserController_Tests ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -311,7 +311,7 @@ public class UserController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -362,7 +362,7 @@ public class UserController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -407,7 +407,7 @@ public class UserController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -462,7 +462,7 @@ public class UserController_Tests ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) @@ -515,7 +515,7 @@ public class UserController_Tests // if (response != null && response.Value != null) // { - // Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); // var result = (BaseResponse)response.Value; // if (result != null) @@ -577,13 +577,13 @@ public class UserController_Tests if (response != null && response.Value != null) { - Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError); + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); var result = (BaseResponse)response.Value; if (result != null) { Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); } else { diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index d27e32e..e20c4b8 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -71,7 +71,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (await this._userService.CheckIfEmailIsValid(request.Data.Email)) + if (await this._userService.CheckIfEmailIsValid(request!.Data!.Email)) { var role = await this._roleService.GetRoleForUser(request.Data.RoleGuid); if (role == null) From e03db76496459eb2003debe19fc05e4f75e675e1 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 19:29:05 +0200 Subject: [PATCH 11/20] Fixing sonarcloud issues --- .editorconfig | 23 ++++++++ .../Controllers/AuthController_Tests.cs | 10 ++-- .../Controllers/RoleController_Tests.cs | 52 +++++++++---------- .../Controllers/UserController_Tests.cs | 28 +++++----- .../JwtAuthorizationAttribute_Tests.cs | 2 +- .../Models/Api/Common/Role/UserRole_Tests.cs | 2 +- .../Common/User/AuthenticatedUser_Tests.cs | 2 +- .../Services/UserService_Tests.cs | 6 +-- .../TestsUtils/ExceptionSqlServerContext.cs | 2 +- MainProject.Tests/TestsUtils/ModelsInit.cs | 2 +- MainProject/Controllers/AuthController.cs | 2 +- MainProject/Controllers/BaseController.cs | 2 +- MainProject/Controllers/RoleController.cs | 12 ++--- MainProject/Controllers/RootController.cs | 2 +- MainProject/Controllers/UserController.cs | 30 +++++------ MainProject/Controllers/VersionController.cs | 2 +- ...alidateModelStateAutomaticallyAttribute.cs | 2 +- MainProject/Core/Database/SqlServerContext.cs | 2 +- .../Core/Filters/ValidationActionFilter.cs | 4 +- .../20240904211920_InitialCreate.cs | 2 +- MainProject/Migrations/20241129231345_Try.cs | 2 +- .../20250311195750_AlterTableUser.cs | 2 +- ...12234517_AlterTableUserMaxLengthIndexes.cs | 2 +- ...20250316014620_AlterTablesUsersAndRoles.cs | 2 +- ...AlterBaseUpdateTimeDeletionTimeNullable.cs | 2 +- ...212722_AlterTableRoleAddedIsNotEditable.cs | 2 +- .../20250426183010_AddingPermissionsTables.cs | 2 +- ...12_AlterTableUsersForPasswordEncryption.cs | 2 +- .../Models/Api/Common/Role/UserRole.cs | 2 +- .../Api/Data/Role/CreateRoleRequestData.cs | 2 +- .../Api/Request/Role/CreateRoleRequest.cs | 2 +- .../Api/Response/Auth/AuthenticateResponse.cs | 2 +- .../Models/Api/Response/BaseResponse.cs | 2 +- .../Api/Response/Role/GetRoleResponse.cs | 2 +- .../Api/Response/User/GetUserResponse.cs | 2 +- MainProject/Models/Common/OperationInfo.cs | 4 +- MainProject/Models/Common/PermissionInfo.cs | 4 +- MainProject/Models/Common/PermissionsFile.cs | 2 +- .../Common/RolePermissionModuleOperation.cs | 2 +- MainProject/Models/Database/Mongo/Log.cs | 2 +- .../Database/SqlServer/PermissionModule.cs | 2 +- .../Database/SqlServer/PermissionOperation.cs | 2 +- .../Database/SqlServer/PermissionSystem.cs | 2 +- .../SqlServer/PermissionSystemModule.cs | 2 +- .../PermissionSystemModuleOperation.cs | 2 +- .../RolePermissionSystemModuleOperation.cs | 2 +- MainProject/Models/Settings/AppSettings.cs | 2 +- .../Models/Settings/DatabaseConnection.cs | 2 +- .../Models/Settings/DatabaseSettings.cs | 2 +- .../Models/Settings/EncryptionSettings.cs | 2 +- MainProject/Models/Settings/JwtSettings.cs | 2 +- .../Models/Settings/OpenApiSettings.cs | 2 +- .../Models/Settings/OpenApiSettingsDetails.cs | 2 +- .../Models/Settings/PermissionsSettings.cs | 2 +- .../Models/Settings/PrivateSettings.cs | 2 +- MainProject/Models/Settings/Settings.cs | 2 +- MainProject/Program.cs | 4 +- MainProject/Services/PermissionService.cs | 2 +- MainProject/Services/UserService.cs | 2 +- MainProject/Utils/FileUtils.cs | 2 +- MainProject/Utils/PasswordUtils.cs | 2 +- MainProject/Utils/ProgramUtils.cs | 4 +- 62 files changed, 152 insertions(+), 129 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c9d40fe --- /dev/null +++ b/.editorconfig @@ -0,0 +1,23 @@ +# top-most EditorConfig file +root = true + +# Core EditorConfig properties +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + + +[*.cs] +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_naming_rule.types.symbols = types +dotnet_naming_rule.types.style = pascal_case +dotnet_naming_rule.types.severity = warning + + +csharp_prefer_braced_block = true:suggestion +csharp_preserve_single_line_blocks = true +csharp_style_expression_bodied_methods = when_on_single_line:suggestion diff --git a/MainProject.Tests/Controllers/AuthController_Tests.cs b/MainProject.Tests/Controllers/AuthController_Tests.cs index cf06461..5c26ea1 100644 --- a/MainProject.Tests/Controllers/AuthController_Tests.cs +++ b/MainProject.Tests/Controllers/AuthController_Tests.cs @@ -66,7 +66,7 @@ public class AuthController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(AuthenticatedUser)); } else @@ -103,7 +103,7 @@ public class AuthController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -173,7 +173,7 @@ public class AuthController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -212,8 +212,8 @@ public class AuthController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index 30320a0..ce2d797 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -75,7 +75,7 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(RoleDto)); } else @@ -110,7 +110,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -172,7 +172,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -207,8 +207,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { @@ -260,7 +260,7 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(RoleDto)); } else @@ -302,8 +302,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.AreEqual("Invalid name", result.Message ); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); + Assert.AreEqual("Invalid name", result.Message); } else { @@ -346,7 +346,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -396,8 +396,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Not created"); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); + Assert.AreEqual("Not created", result.Message); } else { @@ -446,7 +446,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -499,8 +499,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { @@ -560,7 +560,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -622,7 +622,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -657,8 +657,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { @@ -713,7 +713,7 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(RoleDto)); } else @@ -791,8 +791,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.AreEqual("Invalid name", result.Message ); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); + Assert.AreEqual("Invalid name", result.Message); } else { @@ -837,7 +837,7 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); Assert.IsTrue(result.Message == "This role is not editable"); } else @@ -879,7 +879,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -927,7 +927,7 @@ public class RoleController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -981,8 +981,8 @@ public class RoleController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 3e383c3..71ef327 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -85,7 +85,7 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(UserDto)); } else @@ -120,7 +120,7 @@ public class UserController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -182,7 +182,7 @@ public class UserController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -217,8 +217,8 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { @@ -270,7 +270,7 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status200OK); + Assert.AreEqual(StatusCodes.Status200OK, result.Status); Assert.IsInstanceOfType(result.Data, typeof(UserDto)); } else @@ -316,7 +316,7 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); Assert.IsTrue(result.Message == "Invalid email"); } else @@ -367,7 +367,7 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); Assert.IsTrue(result.Message == "Role not found"); } else @@ -412,7 +412,7 @@ public class UserController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Assert.IsTrue(result.Message == "Request is not well formed"); // } // else @@ -467,8 +467,8 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); - Assert.IsTrue(result.Message == "Not created"); + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); + Assert.AreEqual("Not created", result.Message); } else { @@ -520,7 +520,7 @@ public class UserController_Tests // var result = (BaseResponse)response.Value; // if (result != null) // { - // Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest); + // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); // Console.WriteLine(JsonConvert.SerializeObject(result)); // Assert.IsTrue(result.Message == "Request is not well formed"); // } @@ -582,8 +582,8 @@ public class UserController_Tests var result = (BaseResponse)response.Value; if (result != null) { - Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError); - Assert.AreEqual("Something went wrong. Unexpected error", result.Message ); + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); } else { diff --git a/MainProject.Tests/Core/Attributes/JwtAuthorizationAttribute_Tests.cs b/MainProject.Tests/Core/Attributes/JwtAuthorizationAttribute_Tests.cs index 1523008..5e1c3fe 100644 --- a/MainProject.Tests/Core/Attributes/JwtAuthorizationAttribute_Tests.cs +++ b/MainProject.Tests/Core/Attributes/JwtAuthorizationAttribute_Tests.cs @@ -143,4 +143,4 @@ public class JwtAuthorizationAttribute_Tests Assert.IsNotInstanceOfType(context.Result, typeof(UnauthorizedResult)); } -} \ No newline at end of file +} diff --git a/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs b/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs index aaa4fb6..f719dab 100644 --- a/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs +++ b/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs @@ -33,4 +33,4 @@ public class UserRole_Tests Assert.Fail($"An exception was thrown: {ex}"); } } -} \ No newline at end of file +} diff --git a/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs b/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs index 3d22813..0ef3de1 100644 --- a/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs +++ b/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs @@ -36,4 +36,4 @@ public class AuthenticatedUser_Tests Assert.Fail($"An exception was thrown: {ex}"); } } -} \ No newline at end of file +} diff --git a/MainProject.Tests/Services/UserService_Tests.cs b/MainProject.Tests/Services/UserService_Tests.cs index a68ec55..910eec4 100644 --- a/MainProject.Tests/Services/UserService_Tests.cs +++ b/MainProject.Tests/Services/UserService_Tests.cs @@ -34,7 +34,7 @@ public class UserService_Tests Console.WriteLine(ex.InnerException); Assert.Fail($"An exception was thrown: {ex.Message}"); } - } + } [TestMethod] public async Task CheckIfEmailIsValid_EmailNotExists() @@ -366,7 +366,7 @@ public class UserService_Tests var user = await _userService.UpdateUserPasswordAsync(_user!, "this-is-a-new-password"); Assert.IsInstanceOfType(user, typeof(User)); Assert.IsNotNull(user); - Assert.IsTrue(user.Password != oldPassword); + Assert.AreNotEqual(user.Password, oldPassword); } else { @@ -424,7 +424,7 @@ public class UserService_Tests var user = await _userService.UpdateUserRoleAsync(_user!, role); Assert.IsInstanceOfType(user, typeof(User)); Assert.IsNotNull(user); - Assert.IsTrue(user.Role?.Id != oldRole?.Id); + Assert.AreNotEqual(user.Role?.Id, oldRole?.Id); } else { diff --git a/MainProject.Tests/TestsUtils/ExceptionSqlServerContext.cs b/MainProject.Tests/TestsUtils/ExceptionSqlServerContext.cs index 7587a75..465bcbd 100644 --- a/MainProject.Tests/TestsUtils/ExceptionSqlServerContext.cs +++ b/MainProject.Tests/TestsUtils/ExceptionSqlServerContext.cs @@ -21,4 +21,4 @@ public class ExceptionSqlServerContext : SqlServerContext } return base.SaveChangesAsync(cancellationToken); } -} \ No newline at end of file +} diff --git a/MainProject.Tests/TestsUtils/ModelsInit.cs b/MainProject.Tests/TestsUtils/ModelsInit.cs index d97f11b..bcbf9a9 100644 --- a/MainProject.Tests/TestsUtils/ModelsInit.cs +++ b/MainProject.Tests/TestsUtils/ModelsInit.cs @@ -33,4 +33,4 @@ public static class ModelsInit }; return role; } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/AuthController.cs b/MainProject/Controllers/AuthController.cs index 9011ee8..9367729 100644 --- a/MainProject/Controllers/AuthController.cs +++ b/MainProject/Controllers/AuthController.cs @@ -53,4 +53,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers } } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/BaseController.cs b/MainProject/Controllers/BaseController.cs index 45c8e75..491b3f5 100644 --- a/MainProject/Controllers/BaseController.cs +++ b/MainProject/Controllers/BaseController.cs @@ -74,4 +74,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers #nullable disable } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/RoleController.cs b/MainProject/Controllers/RoleController.cs index 966f168..226e960 100644 --- a/MainProject/Controllers/RoleController.cs +++ b/MainProject/Controllers/RoleController.cs @@ -67,9 +67,9 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - if (await this._roleService.CheckIfNameIsValid(request.Data.Name)) + if (await this._roleService.CheckIfNameIsValid(request!.Data!.Name)) { - var role = await this._roleService.CreateRoleAsync(request.Data); + var role = await this._roleService.CreateRoleAsync(request!.Data); if (role == null || String.IsNullOrEmpty(role.Guid)) { @@ -121,8 +121,8 @@ namespace BasicDotnetTemplate.MainProject.Controllers } if ( - await this._roleService.CheckIfNameIsValid(request.Data.Name) || - await this._roleService.CheckIfNameIsValid(request.Data.Name, guid) + await this._roleService.CheckIfNameIsValid(request!.Data!.Name) || + await this._roleService.CheckIfNameIsValid(request!.Data!.Name, guid) ) { role = await this._roleService.UpdateRoleAsync(request.Data, role); @@ -167,7 +167,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return NotFound(); } - await this._roleService.DeleteRoleAsync(role); + await this._roleService.DeleteRoleAsync(role); return Success(String.Empty); } @@ -185,4 +185,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/RootController.cs b/MainProject/Controllers/RootController.cs index f48b1b0..9d38eca 100644 --- a/MainProject/Controllers/RootController.cs +++ b/MainProject/Controllers/RootController.cs @@ -15,4 +15,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers return Ok(); } } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index e20c4b8..72b46a7 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -25,7 +25,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers this._userService = userService; this._roleService = roleService; } - + [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] @@ -73,13 +73,13 @@ namespace BasicDotnetTemplate.MainProject.Controllers { if (await this._userService.CheckIfEmailIsValid(request!.Data!.Email)) { - var role = await this._roleService.GetRoleForUser(request.Data.RoleGuid); + var role = await this._roleService.GetRoleForUser(request!.Data!.RoleGuid); if (role == null) { return BadRequest("Role not found"); } - var user = await this._userService.CreateUserAsync(request.Data, role); + var user = await this._userService.CreateUserAsync(request!.Data, role); if (user == null || String.IsNullOrEmpty(user.Guid)) { @@ -119,7 +119,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers try { var user = await this._userService.GetUserByGuidAsync(guid); - if(user == null) + if (user == null) { return NotFound(); } @@ -129,7 +129,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers var userDto = _mapper?.Map(user); return Success(String.Empty, userDto); - + } catch (Exception exception) { @@ -141,7 +141,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return InternalServerError(message); } - } + } [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] @@ -154,7 +154,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers try { var user = await this._userService.GetUserByGuidAsync(guid); - if(user == null) + if (user == null) { return NotFound(); } @@ -164,7 +164,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers var userDto = _mapper?.Map(user); return Success(String.Empty, userDto); - + } catch (Exception exception) { @@ -176,7 +176,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return InternalServerError(message); } - } + } [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] @@ -195,7 +195,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } var user = await this._userService.GetUserByGuidAsync(guid); - if(user == null) + if (user == null) { return NotFound(); } @@ -205,7 +205,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers var userDto = _mapper?.Map(user); return Success(String.Empty, userDto); - + } catch (Exception exception) { @@ -217,8 +217,8 @@ namespace BasicDotnetTemplate.MainProject.Controllers return InternalServerError(message); } - } - + } + [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpDelete("{guid}")] @@ -239,7 +239,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers await this._userService.DeleteUserAsync(user); - return Success(String.Empty); + return Success(String.Empty); } catch (Exception exception) { @@ -254,4 +254,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers } } -} \ No newline at end of file +} diff --git a/MainProject/Controllers/VersionController.cs b/MainProject/Controllers/VersionController.cs index ee527ed..3d81653 100644 --- a/MainProject/Controllers/VersionController.cs +++ b/MainProject/Controllers/VersionController.cs @@ -16,4 +16,4 @@ namespace BasicDotnetTemplate.MainProject.Controllers return Success(String.Empty, _appSettings?.Settings?.Version); } } -} \ No newline at end of file +} diff --git a/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs b/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs index 72c8d08..ad8cd1b 100644 --- a/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs +++ b/MainProject/Core/Attributes/ValidateModelStateAutomaticallyAttribute.cs @@ -9,4 +9,4 @@ namespace BasicDotnetTemplate.MainProject.Core.Attributes [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class ModelStateValidationHandledByFilterAttribute : Attribute { } -} \ No newline at end of file +} diff --git a/MainProject/Core/Database/SqlServerContext.cs b/MainProject/Core/Database/SqlServerContext.cs index f36d364..16b0ae9 100644 --- a/MainProject/Core/Database/SqlServerContext.cs +++ b/MainProject/Core/Database/SqlServerContext.cs @@ -18,7 +18,7 @@ namespace BasicDotnetTemplate.MainProject.Core.Database public DbSet PermissionOperations { get; set; } public DbSet PermissionSystems { get; set; } public DbSet PermissionSystemModules { get; set; } - public DbSet PermissionSystemModuleOperations { get; set; } + public DbSet PermissionSystemModuleOperations { get; set; } public DbSet RolePermissionSystemModuleOperations { get; set; } public DbSet Roles { get; set; } public DbSet Users { get; set; } diff --git a/MainProject/Core/Filters/ValidationActionFilter.cs b/MainProject/Core/Filters/ValidationActionFilter.cs index 16f942a..a5c6fc9 100644 --- a/MainProject/Core/Filters/ValidationActionFilter.cs +++ b/MainProject/Core/Filters/ValidationActionFilter.cs @@ -13,7 +13,7 @@ namespace BasicDotnetTemplate.MainProject.Core.Filters if (!context.ModelState.IsValid) { context.Result = new BadRequestObjectResult(new { message = _requestNotWellFormedMessage, errors = context.ModelState }); - return; + return; } var requestBody = context.ActionArguments.Values.FirstOrDefault(arg => arg != null && !arg.GetType().IsPrimitive && !(arg is string)); @@ -27,4 +27,4 @@ namespace BasicDotnetTemplate.MainProject.Core.Filters await next(); } } -} \ No newline at end of file +} diff --git a/MainProject/Migrations/20240904211920_InitialCreate.cs b/MainProject/Migrations/20240904211920_InitialCreate.cs index ed4ccbc..d7cf0c6 100644 --- a/MainProject/Migrations/20240904211920_InitialCreate.cs +++ b/MainProject/Migrations/20240904211920_InitialCreate.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20241129231345_Try.cs b/MainProject/Migrations/20241129231345_Try.cs index 46addf6..29573f2 100644 --- a/MainProject/Migrations/20241129231345_Try.cs +++ b/MainProject/Migrations/20241129231345_Try.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250311195750_AlterTableUser.cs b/MainProject/Migrations/20250311195750_AlterTableUser.cs index 26df65b..b846699 100644 --- a/MainProject/Migrations/20250311195750_AlterTableUser.cs +++ b/MainProject/Migrations/20250311195750_AlterTableUser.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250312234517_AlterTableUserMaxLengthIndexes.cs b/MainProject/Migrations/20250312234517_AlterTableUserMaxLengthIndexes.cs index 862a803..ca6e66d 100644 --- a/MainProject/Migrations/20250312234517_AlterTableUserMaxLengthIndexes.cs +++ b/MainProject/Migrations/20250312234517_AlterTableUserMaxLengthIndexes.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250316014620_AlterTablesUsersAndRoles.cs b/MainProject/Migrations/20250316014620_AlterTablesUsersAndRoles.cs index b3192e0..bae0d5a 100644 --- a/MainProject/Migrations/20250316014620_AlterTablesUsersAndRoles.cs +++ b/MainProject/Migrations/20250316014620_AlterTablesUsersAndRoles.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250316212343_AlterBaseUpdateTimeDeletionTimeNullable.cs b/MainProject/Migrations/20250316212343_AlterBaseUpdateTimeDeletionTimeNullable.cs index 5c7c4c9..1d789d6 100644 --- a/MainProject/Migrations/20250316212343_AlterBaseUpdateTimeDeletionTimeNullable.cs +++ b/MainProject/Migrations/20250316212343_AlterBaseUpdateTimeDeletionTimeNullable.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250316212722_AlterTableRoleAddedIsNotEditable.cs b/MainProject/Migrations/20250316212722_AlterTableRoleAddedIsNotEditable.cs index 423f594..ecb0ae0 100644 --- a/MainProject/Migrations/20250316212722_AlterTableRoleAddedIsNotEditable.cs +++ b/MainProject/Migrations/20250316212722_AlterTableRoleAddedIsNotEditable.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250426183010_AddingPermissionsTables.cs b/MainProject/Migrations/20250426183010_AddingPermissionsTables.cs index 3390e0d..7edef53 100644 --- a/MainProject/Migrations/20250426183010_AddingPermissionsTables.cs +++ b/MainProject/Migrations/20250426183010_AddingPermissionsTables.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs index 3fd90e8..585901a 100644 --- a/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs +++ b/MainProject/Migrations/20250617183212_AlterTableUsersForPasswordEncryption.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/MainProject/Models/Api/Common/Role/UserRole.cs b/MainProject/Models/Api/Common/Role/UserRole.cs index b568ca7..b5b6097 100644 --- a/MainProject/Models/Api/Common/Role/UserRole.cs +++ b/MainProject/Models/Api/Common/Role/UserRole.cs @@ -9,7 +9,7 @@ public class UserRole public string? Name { get; set; } #nullable disable - public UserRole() {} + public UserRole() { } public UserRole(DatabaseSqlServer.Role role) { diff --git a/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs b/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs index 9cff830..0a6a1a9 100644 --- a/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs +++ b/MainProject/Models/Api/Data/Role/CreateRoleRequestData.cs @@ -8,4 +8,4 @@ public class CreateRoleRequestData public required string Name { get; set; } public required bool IsNotEditable { get; set; } -} \ No newline at end of file +} diff --git a/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs b/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs index d83636a..3d2df0c 100644 --- a/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs +++ b/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs @@ -7,4 +7,4 @@ public class CreateRoleRequest #nullable enable public CreateRoleRequestData? Data { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Api/Response/Auth/AuthenticateResponse.cs b/MainProject/Models/Api/Response/Auth/AuthenticateResponse.cs index 8d36f75..8827d00 100644 --- a/MainProject/Models/Api/Response/Auth/AuthenticateResponse.cs +++ b/MainProject/Models/Api/Response/Auth/AuthenticateResponse.cs @@ -5,4 +5,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; public class AuthenticateResponse : BaseResponse { public AuthenticateResponse(int status, string? message, AuthenticatedUser? data) : base(status, message, data) { } -} \ No newline at end of file +} diff --git a/MainProject/Models/Api/Response/BaseResponse.cs b/MainProject/Models/Api/Response/BaseResponse.cs index 2b87876..70c7e99 100644 --- a/MainProject/Models/Api/Response/BaseResponse.cs +++ b/MainProject/Models/Api/Response/BaseResponse.cs @@ -16,4 +16,4 @@ public class BaseResponse public virtual dynamic? Data { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Api/Response/Role/GetRoleResponse.cs b/MainProject/Models/Api/Response/Role/GetRoleResponse.cs index 957646c..a061159 100644 --- a/MainProject/Models/Api/Response/Role/GetRoleResponse.cs +++ b/MainProject/Models/Api/Response/Role/GetRoleResponse.cs @@ -5,4 +5,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Response.Role; public class GetRoleResponse : BaseResponse { public GetRoleResponse(int status, string? message, RoleDto? data) : base(status, message, data) { } -} \ No newline at end of file +} diff --git a/MainProject/Models/Api/Response/User/GetUserResponse.cs b/MainProject/Models/Api/Response/User/GetUserResponse.cs index b1979fa..b0989a6 100644 --- a/MainProject/Models/Api/Response/User/GetUserResponse.cs +++ b/MainProject/Models/Api/Response/User/GetUserResponse.cs @@ -5,4 +5,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Response.User; public class GetUserResponse : BaseResponse { public GetUserResponse(int status, string? message, UserDto? data) : base(status, message, data) { } -} \ No newline at end of file +} diff --git a/MainProject/Models/Common/OperationInfo.cs b/MainProject/Models/Common/OperationInfo.cs index 7e9a9a8..eb3a0dd 100644 --- a/MainProject/Models/Common/OperationInfo.cs +++ b/MainProject/Models/Common/OperationInfo.cs @@ -4,6 +4,6 @@ public class OperationInfo { #nullable enable public string? Operation { get; set; } - public List? Roles {get; set; } + public List? Roles { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Common/PermissionInfo.cs b/MainProject/Models/Common/PermissionInfo.cs index 558fc5d..369f2d6 100644 --- a/MainProject/Models/Common/PermissionInfo.cs +++ b/MainProject/Models/Common/PermissionInfo.cs @@ -4,6 +4,6 @@ public class PermissionInfo { #nullable enable public string? System { get; set; } - public List? RolePermissionModuleOperations {get; set; } + public List? RolePermissionModuleOperations { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Common/PermissionsFile.cs b/MainProject/Models/Common/PermissionsFile.cs index f5a4d7b..c515d92 100644 --- a/MainProject/Models/Common/PermissionsFile.cs +++ b/MainProject/Models/Common/PermissionsFile.cs @@ -5,4 +5,4 @@ public class PermissionsFile #nullable enable public List? PermissionInfos { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Common/RolePermissionModuleOperation.cs b/MainProject/Models/Common/RolePermissionModuleOperation.cs index 6d132e5..3af3e33 100644 --- a/MainProject/Models/Common/RolePermissionModuleOperation.cs +++ b/MainProject/Models/Common/RolePermissionModuleOperation.cs @@ -6,4 +6,4 @@ public class RolePermissionModuleOperation public string? Module { get; set; } public List? Operations { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/Mongo/Log.cs b/MainProject/Models/Database/Mongo/Log.cs index f3d4e92..7694b26 100644 --- a/MainProject/Models/Database/Mongo/Log.cs +++ b/MainProject/Models/Database/Mongo/Log.cs @@ -8,4 +8,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.Mongo [BsonId] public ObjectId Id { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/PermissionModule.cs b/MainProject/Models/Database/SqlServer/PermissionModule.cs index dba3a92..72baa47 100644 --- a/MainProject/Models/Database/SqlServer/PermissionModule.cs +++ b/MainProject/Models/Database/SqlServer/PermissionModule.cs @@ -8,4 +8,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer public required string Name { get; set; } public required bool Enabled { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/PermissionOperation.cs b/MainProject/Models/Database/SqlServer/PermissionOperation.cs index 4080277..7770331 100644 --- a/MainProject/Models/Database/SqlServer/PermissionOperation.cs +++ b/MainProject/Models/Database/SqlServer/PermissionOperation.cs @@ -7,4 +7,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer [MaxLength(100)] public required string Name { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/PermissionSystem.cs b/MainProject/Models/Database/SqlServer/PermissionSystem.cs index 7b28d33..8f5e185 100644 --- a/MainProject/Models/Database/SqlServer/PermissionSystem.cs +++ b/MainProject/Models/Database/SqlServer/PermissionSystem.cs @@ -8,4 +8,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer public required string Name { get; set; } public required bool Enabled { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/PermissionSystemModule.cs b/MainProject/Models/Database/SqlServer/PermissionSystemModule.cs index 84eef1f..2ce3eae 100644 --- a/MainProject/Models/Database/SqlServer/PermissionSystemModule.cs +++ b/MainProject/Models/Database/SqlServer/PermissionSystemModule.cs @@ -10,4 +10,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer public required PermissionModule PermissionModule { get; set; } public required bool Enabled { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/PermissionSystemModuleOperation.cs b/MainProject/Models/Database/SqlServer/PermissionSystemModuleOperation.cs index deb5d8b..f716058 100644 --- a/MainProject/Models/Database/SqlServer/PermissionSystemModuleOperation.cs +++ b/MainProject/Models/Database/SqlServer/PermissionSystemModuleOperation.cs @@ -10,4 +10,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer public required PermissionSystemModule PermissionSystemModule { get; set; } public required PermissionOperation PermissionOperation { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Database/SqlServer/RolePermissionSystemModuleOperation.cs b/MainProject/Models/Database/SqlServer/RolePermissionSystemModuleOperation.cs index d42be00..d1f437a 100644 --- a/MainProject/Models/Database/SqlServer/RolePermissionSystemModuleOperation.cs +++ b/MainProject/Models/Database/SqlServer/RolePermissionSystemModuleOperation.cs @@ -10,4 +10,4 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer public required Role Role { get; set; } public required PermissionSystemModuleOperation PermissionSystemModuleOperation { get; set; } } -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/AppSettings.cs b/MainProject/Models/Settings/AppSettings.cs index 3df03e9..b337c1b 100644 --- a/MainProject/Models/Settings/AppSettings.cs +++ b/MainProject/Models/Settings/AppSettings.cs @@ -11,4 +11,4 @@ public class AppSettings public EncryptionSettings? EncryptionSettings { get; set; } public PermissionsSettings? PermissionsSettings { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/DatabaseConnection.cs b/MainProject/Models/Settings/DatabaseConnection.cs index e6d867d..09ba894 100644 --- a/MainProject/Models/Settings/DatabaseConnection.cs +++ b/MainProject/Models/Settings/DatabaseConnection.cs @@ -7,4 +7,4 @@ public class DatabaseConnection public string? Postgres { get; set; } public string? Mongodb { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/DatabaseSettings.cs b/MainProject/Models/Settings/DatabaseSettings.cs index 3ac3be2..ead53f7 100644 --- a/MainProject/Models/Settings/DatabaseSettings.cs +++ b/MainProject/Models/Settings/DatabaseSettings.cs @@ -7,4 +7,4 @@ public class DatabaseSettings public string? MongoDbConnectionString { get; set; } public string? PostgreSQLConnectionString { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/EncryptionSettings.cs b/MainProject/Models/Settings/EncryptionSettings.cs index 0a03110..910d911 100644 --- a/MainProject/Models/Settings/EncryptionSettings.cs +++ b/MainProject/Models/Settings/EncryptionSettings.cs @@ -7,4 +7,4 @@ public class EncryptionSettings public string? Salt { get; set; } public int? Iterations { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/JwtSettings.cs b/MainProject/Models/Settings/JwtSettings.cs index 23f3690..a578085 100644 --- a/MainProject/Models/Settings/JwtSettings.cs +++ b/MainProject/Models/Settings/JwtSettings.cs @@ -9,4 +9,4 @@ public class JwtSettings public int? ExpiredAfterMinsOfInactivity { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/OpenApiSettings.cs b/MainProject/Models/Settings/OpenApiSettings.cs index 35aa38d..6a909c8 100644 --- a/MainProject/Models/Settings/OpenApiSettings.cs +++ b/MainProject/Models/Settings/OpenApiSettings.cs @@ -7,4 +7,4 @@ public class OpenApiSettings public OpenApiSettingsDetails? OpenApiContact { get; set; } public OpenApiSettingsDetails? OpenApiLicense { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/OpenApiSettingsDetails.cs b/MainProject/Models/Settings/OpenApiSettingsDetails.cs index 08d5d97..dd2ea10 100644 --- a/MainProject/Models/Settings/OpenApiSettingsDetails.cs +++ b/MainProject/Models/Settings/OpenApiSettingsDetails.cs @@ -6,4 +6,4 @@ public class OpenApiSettingsDetails public string? Name { get; set; } public string? Url { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/PermissionsSettings.cs b/MainProject/Models/Settings/PermissionsSettings.cs index 495dc9a..82c485f 100644 --- a/MainProject/Models/Settings/PermissionsSettings.cs +++ b/MainProject/Models/Settings/PermissionsSettings.cs @@ -5,4 +5,4 @@ public class PermissionsSettings #nullable enable public string? FilePath { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/PrivateSettings.cs b/MainProject/Models/Settings/PrivateSettings.cs index 0ad3b8b..ffd9ebf 100644 --- a/MainProject/Models/Settings/PrivateSettings.cs +++ b/MainProject/Models/Settings/PrivateSettings.cs @@ -5,4 +5,4 @@ public class PrivateSettings #nullable enable public DatabaseConnection? DatabaseConnection { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Models/Settings/Settings.cs b/MainProject/Models/Settings/Settings.cs index 2932223..001b510 100644 --- a/MainProject/Models/Settings/Settings.cs +++ b/MainProject/Models/Settings/Settings.cs @@ -7,4 +7,4 @@ public class Settings public string? Version { get; set; } public string? Description { get; set; } #nullable disable -} \ No newline at end of file +} diff --git a/MainProject/Program.cs b/MainProject/Program.cs index e6213b2..b887e91 100644 --- a/MainProject/Program.cs +++ b/MainProject/Program.cs @@ -1,4 +1,4 @@ -using NLog; +using NLog; using BasicDotnetTemplate.MainProject.Models.Settings; using System.Reflection; using BasicDotnetTemplate.MainProject.Utils; @@ -60,4 +60,4 @@ internal static class Program NLog.LogManager.Shutdown(); // Flush and close down internal threads and timers } -} \ No newline at end of file +} diff --git a/MainProject/Services/PermissionService.cs b/MainProject/Services/PermissionService.cs index 8ab2923..bc695b5 100644 --- a/MainProject/Services/PermissionService.cs +++ b/MainProject/Services/PermissionService.cs @@ -1275,4 +1275,4 @@ public class PermissionService : BaseService, IPermissionService -} \ No newline at end of file +} diff --git a/MainProject/Services/UserService.cs b/MainProject/Services/UserService.cs index 2f04ce5..ac6f01b 100644 --- a/MainProject/Services/UserService.cs +++ b/MainProject/Services/UserService.cs @@ -191,7 +191,7 @@ public class UserService : BaseService, IUserService user.PasswordSalt = salt; user.PasswordPepper = pepper; - user.PasswordIterations = iterations; + user.PasswordIterations = iterations; user.Password = CryptUtils.GeneratePassword(newPassword, salt, iterations, pepper); user.UpdateTime = DateTime.UtcNow; user.UpdateUserId = this.GetCurrentUserId(); diff --git a/MainProject/Utils/FileUtils.cs b/MainProject/Utils/FileUtils.cs index 5c7be6e..6c84819 100644 --- a/MainProject/Utils/FileUtils.cs +++ b/MainProject/Utils/FileUtils.cs @@ -39,4 +39,4 @@ public static class FileUtils } } -} \ No newline at end of file +} diff --git a/MainProject/Utils/PasswordUtils.cs b/MainProject/Utils/PasswordUtils.cs index b1cd1fc..f61ad80 100644 --- a/MainProject/Utils/PasswordUtils.cs +++ b/MainProject/Utils/PasswordUtils.cs @@ -29,7 +29,7 @@ public static partial class PasswordUtils private static partial Regex RegexSpecial(); private static readonly Regex RegexIdenticalChars = new( - @"(\S)\1{2,}", + @"(\S)\1{2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled, TimeSpan.FromMilliseconds(100) ); diff --git a/MainProject/Utils/ProgramUtils.cs b/MainProject/Utils/ProgramUtils.cs index 0ab8959..b2cd6a0 100644 --- a/MainProject/Utils/ProgramUtils.cs +++ b/MainProject/Utils/ProgramUtils.cs @@ -142,7 +142,7 @@ public static class ProgramUtils builder.Services.AddAuthorization(); builder.Services.AddControllers(options => { - options.Filters.Add(); + options.Filters.Add(); }); builder.Services.AddEndpointsApiExplorer(); @@ -295,4 +295,4 @@ public static class ProgramUtils } } -} \ No newline at end of file +} From 5c1eacd85e3803a72041128c0c4cefb73d8dae9a Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 19:45:02 +0200 Subject: [PATCH 12/20] Fixing sonarcloud issues --- .editorconfig | 8 -------- MainProject.Tests/Controllers/RoleController_Tests.cs | 2 +- MainProject.Tests/Controllers/UserController_Tests.cs | 2 +- .../Models/Api/Common/Role/UserRole_Tests.cs | 4 ++-- .../Models/Api/Common/User/AuthenticatedUser_Tests.cs | 6 +++--- MainProject/Controllers/AuthController.cs | 2 +- MainProject/Controllers/UserController.cs | 2 +- 7 files changed, 9 insertions(+), 17 deletions(-) diff --git a/.editorconfig b/.editorconfig index c9d40fe..b421b34 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,14 +10,6 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true - -[*.cs] -dotnet_naming_style.pascal_case.capitalization = pascal_case -dotnet_naming_rule.types.symbols = types -dotnet_naming_rule.types.style = pascal_case -dotnet_naming_rule.types.severity = warning - - csharp_prefer_braced_block = true:suggestion csharp_preserve_single_line_blocks = true csharp_style_expression_bodied_methods = when_on_single_line:suggestion diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index ce2d797..75489e7 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -838,7 +838,7 @@ public class RoleController_Tests if (result != null) { Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - Assert.IsTrue(result.Message == "This role is not editable"); + Assert.AreEqual("This role is not editable", result.Message); } else { diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 71ef327..572f354 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -317,7 +317,7 @@ public class UserController_Tests if (result != null) { Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - Assert.IsTrue(result.Message == "Invalid email"); + Assert.AreEqual("Invalid email", result.Message); } else { diff --git a/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs b/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs index f719dab..91f2779 100644 --- a/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs +++ b/MainProject.Tests/Models/Api/Common/Role/UserRole_Tests.cs @@ -23,9 +23,9 @@ public class UserRole_Tests try { DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - UserRole userRole = new UserRole(role); + UserRole userRole = new(role); - Assert.IsTrue(userRole.Name == role.Name); + Assert.AreEqual(role.Name, userRole.Name); } catch (Exception ex) { diff --git a/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs b/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs index 0ef3de1..448aed2 100644 --- a/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs +++ b/MainProject.Tests/Models/Api/Common/User/AuthenticatedUser_Tests.cs @@ -25,9 +25,9 @@ public class AuthenticatedUser_Tests DatabaseSqlServer.User user = ModelsInit.CreateUser(); AuthenticatedUser authenticatedUser = new AuthenticatedUser(user); - Assert.IsTrue(authenticatedUser.FirstName == user.FirstName); - Assert.IsTrue(authenticatedUser.LastName == user.LastName); - Assert.IsTrue(authenticatedUser.Email == user.Email); + Assert.AreEqual(user.FirstName, authenticatedUser.FirstName); + Assert.AreEqual(user.LastName, authenticatedUser.LastName); + Assert.AreEqual(user.Email, authenticatedUser.Email); Assert.IsInstanceOfType(authenticatedUser.Role, typeof(UserRole)); } catch (Exception ex) diff --git a/MainProject/Controllers/AuthController.cs b/MainProject/Controllers/AuthController.cs index 9367729..bf8a891 100644 --- a/MainProject/Controllers/AuthController.cs +++ b/MainProject/Controllers/AuthController.cs @@ -32,7 +32,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - var data = await this._authService.AuthenticateAsync(request.Data); + var data = await this._authService.AuthenticateAsync(request!.Data); if (data == null) { diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index 72b46a7..32def4b 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -124,7 +124,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return NotFound(); } - user = await this._userService.UpdateUserAsync(request.Data, user); + user = await this._userService.UpdateUserAsync(request!.Data, user); var userDto = _mapper?.Map(user); From 73043970a8aa8370a0b08a0776643fb976f9b9b2 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 20:08:34 +0200 Subject: [PATCH 13/20] Fixing sonarcloud issues --- MainProject.Tests/Controllers/UserController_Tests.cs | 2 +- MainProject/Controllers/AuthController.cs | 2 +- MainProject/Controllers/UserController.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 572f354..38d71c3 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -368,7 +368,7 @@ public class UserController_Tests if (result != null) { Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - Assert.IsTrue(result.Message == "Role not found"); + Assert.AreEqual("Role not found", result.Message); } else { diff --git a/MainProject/Controllers/AuthController.cs b/MainProject/Controllers/AuthController.cs index bf8a891..a54e764 100644 --- a/MainProject/Controllers/AuthController.cs +++ b/MainProject/Controllers/AuthController.cs @@ -32,7 +32,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - var data = await this._authService.AuthenticateAsync(request!.Data); + var data = await this._authService.AuthenticateAsync(request!.Data!); if (data == null) { diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index 32def4b..965d28c 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -124,7 +124,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers return NotFound(); } - user = await this._userService.UpdateUserAsync(request!.Data, user); + user = await this._userService.UpdateUserAsync(request!.Data!, user); var userDto = _mapper?.Map(user); From 2d7db3d91912a9a628d808b20abf5f44dfd35424 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 20:48:17 +0200 Subject: [PATCH 14/20] Minor fixes for model validation --- .../Models/Api/Common/User/AuthenticatedUser.cs | 2 +- .../Models/Api/Data/Auth/AuthenticateRequestData.cs | 10 ++++++---- .../Models/Api/Request/Auth/AuthenticateRequest.cs | 6 +++--- .../Models/Api/Request/Role/CreateRoleRequest.cs | 6 +++--- .../Models/Api/Request/User/CreateUserRequest.cs | 6 +++--- .../Models/Api/Request/User/UpdateUserRequest.cs | 6 +++--- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/MainProject/Models/Api/Common/User/AuthenticatedUser.cs b/MainProject/Models/Api/Common/User/AuthenticatedUser.cs index 1791717..e2b871a 100644 --- a/MainProject/Models/Api/Common/User/AuthenticatedUser.cs +++ b/MainProject/Models/Api/Common/User/AuthenticatedUser.cs @@ -19,7 +19,7 @@ public class AuthenticatedUser FirstName = user.FirstName; LastName = user.LastName; Email = user.Email; - Role = new UserRole(); + Role = new UserRole(user.Role!); } } diff --git a/MainProject/Models/Api/Data/Auth/AuthenticateRequestData.cs b/MainProject/Models/Api/Data/Auth/AuthenticateRequestData.cs index ef1c7c1..1e7801f 100644 --- a/MainProject/Models/Api/Data/Auth/AuthenticateRequestData.cs +++ b/MainProject/Models/Api/Data/Auth/AuthenticateRequestData.cs @@ -1,11 +1,13 @@ +using System.ComponentModel.DataAnnotations; + namespace BasicDotnetTemplate.MainProject.Models.Api.Data.Auth; public class AuthenticateRequestData { -#nullable enable - public string? Email { get; set; } - public string? Password { get; set; } -#nullable disable + [Required(ErrorMessage = "Email is required")] + public required string Email { get; set; } + [Required(ErrorMessage = "Password is required")] + public required string Password { get; set; } } diff --git a/MainProject/Models/Api/Request/Auth/AuthenticateRequest.cs b/MainProject/Models/Api/Request/Auth/AuthenticateRequest.cs index f7a8e52..ecd9624 100644 --- a/MainProject/Models/Api/Request/Auth/AuthenticateRequest.cs +++ b/MainProject/Models/Api/Request/Auth/AuthenticateRequest.cs @@ -1,12 +1,12 @@ +using System.ComponentModel.DataAnnotations; using BasicDotnetTemplate.MainProject.Models.Api.Data.Auth; namespace BasicDotnetTemplate.MainProject.Models.Api.Request.Auth; public class AuthenticateRequest { -#nullable enable - public AuthenticateRequestData? Data { get; set; } -#nullable disable + [Required(ErrorMessage = "Data is required")] + public required AuthenticateRequestData Data { get; set; } } diff --git a/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs b/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs index 3d2df0c..79c2c72 100644 --- a/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs +++ b/MainProject/Models/Api/Request/Role/CreateRoleRequest.cs @@ -1,10 +1,10 @@ +using System.ComponentModel.DataAnnotations; using BasicDotnetTemplate.MainProject.Models.Api.Data.Role; namespace BasicDotnetTemplate.MainProject.Models.Api.Request.Role; public class CreateRoleRequest { -#nullable enable - public CreateRoleRequestData? Data { get; set; } -#nullable disable + [Required(ErrorMessage = "Data is required")] + public required CreateRoleRequestData? Data { get; set; } } diff --git a/MainProject/Models/Api/Request/User/CreateUserRequest.cs b/MainProject/Models/Api/Request/User/CreateUserRequest.cs index 36ba57c..09dfb41 100644 --- a/MainProject/Models/Api/Request/User/CreateUserRequest.cs +++ b/MainProject/Models/Api/Request/User/CreateUserRequest.cs @@ -1,12 +1,12 @@ +using System.ComponentModel.DataAnnotations; using BasicDotnetTemplate.MainProject.Models.Api.Data.User; namespace BasicDotnetTemplate.MainProject.Models.Api.Request.User; public class CreateUserRequest { -#nullable enable - public CreateUserRequestData? Data { get; set; } -#nullable disable + [Required(ErrorMessage = "Data is required")] + public required CreateUserRequestData Data { get; set; } } diff --git a/MainProject/Models/Api/Request/User/UpdateUserRequest.cs b/MainProject/Models/Api/Request/User/UpdateUserRequest.cs index c2bf2df..7e9ee40 100644 --- a/MainProject/Models/Api/Request/User/UpdateUserRequest.cs +++ b/MainProject/Models/Api/Request/User/UpdateUserRequest.cs @@ -1,12 +1,12 @@ +using System.ComponentModel.DataAnnotations; using BasicDotnetTemplate.MainProject.Models.Api.Data.User; namespace BasicDotnetTemplate.MainProject.Models.Api.Request.User; public class UpdateUserRequest { -#nullable enable - public UpdateUserRequestData? Data { get; set; } -#nullable disable + [Required(ErrorMessage = "Data is required")] + public required UpdateUserRequestData Data { get; set; } } From e1d1381a5c60d17f66bf323bb8dea29a5bf0f768 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 23:14:43 +0200 Subject: [PATCH 15/20] Adding tests for ValidationActionFilter --- .../Filters/ValidationActionFilter_Tests.cs | 136 ++++++++++++++++++ .../Core/Filters/ValidationActionFilter.cs | 19 ++- .../Models/Api/Base/ValidationError.cs | 9 ++ 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs create mode 100644 MainProject/Models/Api/Base/ValidationError.cs diff --git a/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs b/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs new file mode 100644 index 0000000..b2c1f24 --- /dev/null +++ b/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs @@ -0,0 +1,136 @@ +using BasicDotnetTemplate.MainProject.Models.Api.Common.User; +using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer; +using Microsoft.AspNetCore.Builder; +using BasicDotnetTemplate.MainProject.Models.Settings; +using BasicDotnetTemplate.MainProject.Utils; +using Microsoft.AspNetCore.Mvc.Filters; +using BasicDotnetTemplate.MainProject.Core.Attributes; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using Microsoft.Extensions.Configuration; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using BasicDotnetTemplate.MainProject.Core.Filters; +using Newtonsoft.Json; +using BasicDotnetTemplate.MainProject.Models.Api.Base; + + +namespace BasicDotnetTemplate.MainProject.Tests; + +[TestClass] +public class ValidationActionFilter_Tests +{ + private readonly string _requestNotWellFormedMessage = "Request is not well formed"; + + private static ActionExecutingContext CreateContext(ModelStateDictionary modelState, object? requestBody = null) + { + var actionContext = new ActionContext( + new DefaultHttpContext(), + new Microsoft.AspNetCore.Routing.RouteData(), + new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor(), + modelState + ); + var actionArguments = new Dictionary(); + + if (requestBody != null) + { + actionArguments.Add("request", requestBody); + } + return new ActionExecutingContext( + actionContext, + [], + actionArguments, + new Mock().Object + ); + } + + [TestMethod] + public void OnActionExecutionAsync_ModelStateInvalid_ReturnsBadRequestAndDoesNotCallNext() + { + // Arrange + var modelState = new ModelStateDictionary(); + modelState.AddModelError("MissingProperty", "MissingProperty is required"); + var context = CreateContext(modelState, new { SomeProp = "Value" }); + var nextCalled = false; + ActionExecutionDelegate next = () => { + nextCalled = true; + return Task.FromResult(new ActionExecutedContext(context, [], new Mock().Object)); + }; + var filter = new ValidationActionFilter(); + // Act + filter.OnActionExecutionAsync(context, next).GetAwaiter().GetResult(); + // Assert + Assert.IsNotNull(context.Result); + var badRequestResult = context.Result as BadRequestObjectResult; + Assert.IsNotNull(badRequestResult); + Assert.IsNotNull(badRequestResult!.Value); + + ValidationError validationError = (ValidationError)badRequestResult.Value; + Assert.AreEqual(_requestNotWellFormedMessage, validationError?.Message); + Assert.IsNotNull(validationError?.Errors); + Assert.IsFalse(modelState.IsValid); + Assert.IsFalse(nextCalled); + } + + [TestMethod] + public void OnActionExecutionAsync_ModelStateValid_RequestBodyNull_ReturnsBadRequestAndDoesNotCallNext() + { + + var modelState = new ModelStateDictionary(); + + var context = CreateContext(modelState, null); + var nextCalled = false; + ActionExecutionDelegate next = () => { + nextCalled = true; + return Task.FromResult(new ActionExecutedContext(context, [], new Mock().Object)); + }; + var filter = new ValidationActionFilter(); + // Act + filter.OnActionExecutionAsync(context, next).GetAwaiter().GetResult(); + // Assert + Assert.IsNotNull(context.Result); + var badRequestResult = context.Result as BadRequestObjectResult; + Assert.IsNotNull(badRequestResult); + Assert.IsNotNull(badRequestResult!.Value); + + ValidationError validationError = (ValidationError)badRequestResult.Value; + Console.WriteLine(JsonConvert.SerializeObject(validationError)); + Assert.AreEqual(_requestNotWellFormedMessage, validationError?.Message); + Assert.IsNull(validationError?.Errors); + Assert.IsTrue(modelState.IsValid); + Assert.IsFalse(nextCalled); + } + + + [TestMethod] + public void OnActionExecutionAsync_ModelStateValid_RequestBodyValid_CallsNextAndDoesNotSetResult() + { + // Arrange + var modelState = new ModelStateDictionary(); + + var requestBody = new TestRequestBody { Value = "Test" }; + var context = CreateContext(modelState, requestBody); + var nextCalled = false; + ActionExecutionDelegate next = () => { + nextCalled = true; + return Task.FromResult(new ActionExecutedContext(context, [], new Mock().Object)); + }; + var filter = new ValidationActionFilter(); + // Act + filter.OnActionExecutionAsync(context, next).GetAwaiter().GetResult(); + // Assert + Assert.IsNull(context.Result); + Assert.IsTrue(nextCalled); + } + + + private class TestRequestBody + { + public string? Value { get; set; } + } + +} diff --git a/MainProject/Core/Filters/ValidationActionFilter.cs b/MainProject/Core/Filters/ValidationActionFilter.cs index a5c6fc9..ef9ca29 100644 --- a/MainProject/Core/Filters/ValidationActionFilter.cs +++ b/MainProject/Core/Filters/ValidationActionFilter.cs @@ -1,3 +1,4 @@ +using BasicDotnetTemplate.MainProject.Models.Api.Base; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System.Threading.Tasks; @@ -12,15 +13,27 @@ namespace BasicDotnetTemplate.MainProject.Core.Filters { if (!context.ModelState.IsValid) { - context.Result = new BadRequestObjectResult(new { message = _requestNotWellFormedMessage, errors = context.ModelState }); + context.Result = new BadRequestObjectResult(new ValidationError + { + Message = _requestNotWellFormedMessage, + Errors = context.ModelState.Where(m => + m.Value != null && m.Value.Errors.Any()) + .ToDictionary( + m => m.Key, + m => m.Value!.Errors.Select(e => e.ErrorMessage).ToList() + ) + }); return; } - var requestBody = context.ActionArguments.Values.FirstOrDefault(arg => arg != null && !arg.GetType().IsPrimitive && !(arg is string)); + var requestBody = context.ActionArguments.Values.FirstOrDefault(arg => arg != null && !arg.GetType().IsPrimitive && arg is not string); if (requestBody == null) { - context.Result = new BadRequestObjectResult(new { message = _requestNotWellFormedMessage }); + context.Result = new BadRequestObjectResult(new ValidationError + { + Message = _requestNotWellFormedMessage + }); return; } diff --git a/MainProject/Models/Api/Base/ValidationError.cs b/MainProject/Models/Api/Base/ValidationError.cs new file mode 100644 index 0000000..c0d76d6 --- /dev/null +++ b/MainProject/Models/Api/Base/ValidationError.cs @@ -0,0 +1,9 @@ +using System; + +namespace BasicDotnetTemplate.MainProject.Models.Api.Base; + +public class ValidationError +{ + public string Message { get; set; } + public Dictionary> Errors { get; set; } +} From 63fab9d827c721941107ca08aee8de49eade474d Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 23:28:28 +0200 Subject: [PATCH 16/20] Removing duplicated lines --- MainProject/Controllers/AuthController.cs | 7 +-- MainProject/Controllers/BaseController.cs | 8 +++- MainProject/Controllers/RoleController.cs | 30 ++---------- MainProject/Controllers/UserController.cs | 50 ++++---------------- MainProject/Controllers/VersionController.cs | 5 +- 5 files changed, 23 insertions(+), 77 deletions(-) diff --git a/MainProject/Controllers/AuthController.cs b/MainProject/Controllers/AuthController.cs index a54e764..fef8838 100644 --- a/MainProject/Controllers/AuthController.cs +++ b/MainProject/Controllers/AuthController.cs @@ -43,12 +43,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } diff --git a/MainProject/Controllers/BaseController.cs b/MainProject/Controllers/BaseController.cs index 491b3f5..d217d39 100644 --- a/MainProject/Controllers/BaseController.cs +++ b/MainProject/Controllers/BaseController.cs @@ -66,9 +66,13 @@ namespace BasicDotnetTemplate.MainProject.Controllers return StatusCode((int)HttpStatusCode.BadRequest, CreateResponse(HttpStatusCode.BadRequest, message, data)); } - protected IActionResult InternalServerError(string message) + protected IActionResult InternalServerError(Exception exception) { - message = String.IsNullOrEmpty(message) ? "Internal server error" : message; + var message = this._somethingWentWrong; + if (!String.IsNullOrEmpty(exception.Message)) + { + message += $". {exception.Message}"; + } return StatusCode((int)HttpStatusCode.InternalServerError, CreateResponse(HttpStatusCode.InternalServerError, message, new object())); } diff --git a/MainProject/Controllers/RoleController.cs b/MainProject/Controllers/RoleController.cs index 226e960..38ddc36 100644 --- a/MainProject/Controllers/RoleController.cs +++ b/MainProject/Controllers/RoleController.cs @@ -47,12 +47,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -88,12 +83,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -101,7 +91,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}")] - [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] public async Task UpdateRoleAsync([FromBody] CreateRoleRequest request, string guid) //NOSONAR @@ -139,12 +129,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -173,12 +158,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index 965d28c..89b0967 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -51,17 +51,12 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } - // [JwtAuthorization()] + [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpPost("create")] [ProducesResponseType(StatusCodes.Status201Created)] @@ -98,12 +93,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -111,7 +101,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}")] - [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] public async Task UpdateUserAsync([FromBody] UpdateUserRequest request, string guid) //NOSONAR @@ -133,12 +123,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -146,7 +131,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}/password")] - [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] public async Task UpdateUserPasswordAsync(string guid, string newPassword) @@ -168,12 +153,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -181,7 +161,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers [JwtAuthorization()] [ModelStateValidationHandledByFilterAttribute] [HttpPut("update/{guid}/role")] - [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status500InternalServerError)] public async Task UpdateUserRoleAsync(string guid, string roleGuid) @@ -209,12 +189,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } @@ -243,12 +218,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers } catch (Exception exception) { - var message = this._somethingWentWrong; - if (!String.IsNullOrEmpty(exception.Message)) - { - message += $". {exception.Message}"; - } - return InternalServerError(message); + return InternalServerError(exception); } } diff --git a/MainProject/Controllers/VersionController.cs b/MainProject/Controllers/VersionController.cs index 3d81653..e818d01 100644 --- a/MainProject/Controllers/VersionController.cs +++ b/MainProject/Controllers/VersionController.cs @@ -11,9 +11,6 @@ namespace BasicDotnetTemplate.MainProject.Controllers ) : base(configuration) { } [HttpGet("get")] - public IActionResult GetVersion() - { - return Success(String.Empty, _appSettings?.Settings?.Version); - } + public IActionResult GetVersion() => Success(String.Empty, _appSettings?.Settings?.Version); } } From 12b4a4d0c82964ce7abb21b17c6983c919bed796 Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Thu, 19 Jun 2025 23:37:25 +0200 Subject: [PATCH 17/20] Removed obsolete tests --- .../Controllers/AuthController_Tests.cs | 75 ---- .../Controllers/RoleController_Tests.cs | 328 ------------------ .../Controllers/UserController_Tests.cs | 170 --------- 3 files changed, 573 deletions(-) diff --git a/MainProject.Tests/Controllers/AuthController_Tests.cs b/MainProject.Tests/Controllers/AuthController_Tests.cs index 5c26ea1..971d602 100644 --- a/MainProject.Tests/Controllers/AuthController_Tests.cs +++ b/MainProject.Tests/Controllers/AuthController_Tests.cs @@ -81,42 +81,6 @@ public class AuthController_Tests } } - // [TestMethod] - // public async Task AuthenticateAsync_AuthenticateRequestDataNull() - // { - // IConfiguration configuration = TestUtils.CreateConfiguration(); - // var authServiceMock = new Mock(); - // var controller = new AuthController(configuration, authServiceMock.Object); - - // var request = new AuthenticateRequest - // { - // Data = null - // }; - // AuthenticatedUser? authenticatedUser = null; - // authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); - // ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task AuthenticateAsync_NotFound() { @@ -148,45 +112,6 @@ public class AuthController_Tests } } - // [TestMethod] - // public async Task AuthenticateAsync_ModelInvalid() - // { - // IConfiguration configuration = TestUtils.CreateConfiguration(); - // var authServiceMock = new Mock(); - // var controller = new AuthController(configuration, authServiceMock.Object); - - // var request = new AuthenticateRequest - // { - // Data = null - // }; - // AuthenticatedUser? authenticatedUser = null; - // authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny())).ReturnsAsync(authenticatedUser); - // controller.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task AuthenticateAsync_Exception() { diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index 75489e7..2e7e9c6 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -89,41 +89,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task GetRoleByGuidAsync_GuidIsEmpty() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // var guid = String.Empty; - // DatabaseSqlServer.Role? role = null; - - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task GetRoleByGuidAsync_NotFound() { @@ -149,43 +114,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task GetRoleByGuidAsync_ModelInvalid() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // var guid = Guid.NewGuid().ToString(); - // DatabaseSqlServer.Role? role = null; - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // _roleController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _roleController.GetRoleByGuidAsync(guid)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task GetRoleByGuidAsync_Exception() { @@ -316,50 +244,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task CreateRoleAsync_CreateRoleRequestDataNull() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - - // CreateRoleRequest request = new CreateRoleRequest() - // { - // Data = null - // }; - - // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - - // _roleServiceMock?.Setup(s => s.CreateRoleAsync( - // It.IsAny() - // )).ReturnsAsync(role); - - // ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task CreateRoleAsync_NotCreated() { @@ -410,56 +294,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task CreateRoleAsync_ModelInvalid() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - - // CreateRoleRequest request = new CreateRoleRequest() - // { - // Data = new CreateRoleRequestData() - // { - // Name = "RoleTest", - // IsNotEditable = true - // } - // }; - - // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - - // _roleServiceMock?.Setup(s => s.CreateRoleAsync( - // It.IsAny() - // )).ReturnsAsync(role); - // _roleController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _roleController.CreateRoleAsync(request)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task CreateRoleAsync_Exception() { @@ -539,41 +373,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task DeleteRoleByGuidAsync_GuidIsEmpty() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // var guid = String.Empty; - // DatabaseSqlServer.Role? role = null; - - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task DeleteRoleByGuidAsync_NotFound() { @@ -599,43 +398,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task DeleteRoleByGuidAsync_ModelInvalid() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // var guid = Guid.NewGuid().ToString(); - // DatabaseSqlServer.Role? role = null; - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // _roleController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _roleController.DeleteRoleByGuidAsync(guid)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task DeleteRoleByGuidAsync_Exception() { @@ -851,96 +613,6 @@ public class RoleController_Tests } } - // [TestMethod] - // public async Task UpdateRoleAsync_CreateRoleRequestDataNull() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - - // CreateRoleRequest request = new CreateRoleRequest() - // { - // Data = null - // }; - - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - // _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); - - // ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - - // [TestMethod] - // public async Task UpdateRoleAsync_ModelInvalid() - // { - // if (_roleController == null) - // { - // Assert.Fail($"_roleController is null"); - // } - - // DatabaseSqlServer.Role role = ModelsInit.CreateRole(); - - // CreateRoleRequest request = new CreateRoleRequest() - // { - // Data = new CreateRoleRequestData() - // { - // Name = "RoleTest", - // IsNotEditable = true - // } - // }; - - // _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); - // _roleServiceMock?.Setup(s => s.CheckIfNameIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - // _roleServiceMock?.Setup(s => s.UpdateRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(role); - // _roleController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task UpdateRoleAsync_Exception() { diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 38d71c3..4a2540f 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -99,41 +99,6 @@ public class UserController_Tests } } - // [TestMethod] - // public async Task GetUserByGuidAsync_GuidIsEmpty() - // { - // if (_userController == null) - // { - // Assert.Fail($"_userController is null"); - // } - - // var guid = String.Empty; - // DatabaseSqlServer.User? user = null; - - // _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); - // ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task GetUserByGuidAsync_NotFound() { @@ -159,43 +124,6 @@ public class UserController_Tests } } - // [TestMethod] - // public async Task GetUserByGuidAsync_ModelInvalid() - // { - // if (_userController == null) - // { - // Assert.Fail($"_userController is null"); - // } - - // var guid = Guid.NewGuid().ToString(); - // DatabaseSqlServer.User? user = null; - // _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); - // _userController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _userController.GetUserByGuidAsync(guid)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } - [TestMethod] public async Task GetUserByGuidAsync_Exception() { @@ -381,51 +309,6 @@ public class UserController_Tests } } - // [TestMethod] - // public async Task CreateUserAsync_CreateUserRequestDataNull() - // { - // if (_userController == null) - // { - // Assert.Fail($"_userController is null"); - // } - - // DatabaseSqlServer.User user = ModelsInit.CreateUser(); - - // CreateUserRequest request = new CreateUserRequest() - // { - // Data = null - // }; - - // _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - - // _userServiceMock?.Setup(s => s.CreateUserAsync( - // It.IsAny(), - // It.IsAny() - // )).ReturnsAsync(user); - - // ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response value is null"); - // } - // } - [TestMethod] public async Task CreateUserAsync_NotCreated() { @@ -481,59 +364,6 @@ public class UserController_Tests } } - // [TestMethod] - // public async Task CreateUserAsync_ModelInvalid() - // { - // if (_userController == null) - // { - // Assert.Fail($"_userController is null"); - // } - - // DatabaseSqlServer.User user = ModelsInit.CreateUser(); - - // CreateUserRequest request = new CreateUserRequest() - // { - // Data = new CreateUserRequestData() - // { - // FirstName = user.FirstName, - // LastName = user.LastName, - // Email = user.Email, - // Password = user.Password - // } - // }; - - // _userServiceMock?.Setup(s => s.CheckIfEmailIsValid(It.IsAny(), It.IsAny())).ReturnsAsync(true); - - // _userServiceMock?.Setup(s => s.CreateUserAsync( - // It.IsAny(), - // It.IsAny() - // )).ReturnsAsync(user); - // _userController.ModelState.AddModelError("Data", "Invalid data"); - // ObjectResult response = (ObjectResult)(await _userController.CreateUserAsync(request)); - - // Assert.IsInstanceOfType(response, typeof(ObjectResult)); - - // if (response != null && response.Value != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); - - // var result = (BaseResponse)response.Value; - // if (result != null) - // { - // Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); - // Console.WriteLine(JsonConvert.SerializeObject(result)); - // Assert.IsTrue(result.Message == "Request is not well formed"); - // } - // else - // { - // Assert.Fail($"Result value is null"); - // } - // } - // else - // { - // Assert.Fail($"Response is null"); - // } - // } [TestMethod] public async Task CreateUserAsync_Exception() From a6193c3c94e82ba4b2e0894ddf3910739a04aafc Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Fri, 20 Jun 2025 20:37:40 +0200 Subject: [PATCH 18/20] Adding tests for CRUD operations on users --- .../Controllers/RoleController_Tests.cs | 5 +- .../Controllers/UserController_Tests.cs | 235 +++++++++++++++++- 2 files changed, 236 insertions(+), 4 deletions(-) diff --git a/MainProject.Tests/Controllers/RoleController_Tests.cs b/MainProject.Tests/Controllers/RoleController_Tests.cs index 2e7e9c6..417d7ac 100644 --- a/MainProject.Tests/Controllers/RoleController_Tests.cs +++ b/MainProject.Tests/Controllers/RoleController_Tests.cs @@ -435,8 +435,6 @@ public class RoleController_Tests #endregion - - #region "UPDATE" [TestMethod] @@ -643,7 +641,7 @@ public class RoleController_Tests It.IsAny(), It.IsAny() )).ThrowsAsync(new Exception("Unexpected error")); - ObjectResult response = (ObjectResult)(await _roleController.UpdateRoleAsync(request, role.Guid)); + ObjectResult response = (ObjectResult)await _roleController.UpdateRoleAsync(request, role.Guid); Assert.IsInstanceOfType(response, typeof(ObjectResult)); if (response != null && response.Value != null) @@ -668,4 +666,5 @@ public class RoleController_Tests } #endregion + } diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 4a2540f..1cf72ef 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -66,6 +66,7 @@ public class UserController_Tests } +#region "GET" [TestMethod] public async Task GetUserByGuidAsync_Should_Return_200_When_Successful() { @@ -159,6 +160,10 @@ public class UserController_Tests } } +#endregion + + +#region "CREATE" [TestMethod] public async Task CreateUserAsync_Success() { @@ -364,7 +369,6 @@ public class UserController_Tests } } - [TestMethod] public async Task CreateUserAsync_Exception() { @@ -425,4 +429,233 @@ public class UserController_Tests Assert.Fail($"Response is null"); } } + +#endregion + +#region "DELETE" + + [TestMethod] + public async Task DeleteRoleByGuidAsync_Success() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + var guid = Guid.NewGuid().ToString(); + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + ObjectResult response = (ObjectResult)await _userController.DeleteUserByGuidAsync(guid); + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); + } + else + { + Assert.Fail($"Response value is null"); + } + } + + [TestMethod] + public async Task DeleteRoleByGuidAsync_NotFound() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + var guid = Guid.NewGuid().ToString(); + DatabaseSqlServer.User? user = null; + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + NotFoundResult response = (NotFoundResult)await _userController.DeleteUserByGuidAsync(guid); + + Assert.IsInstanceOfType(response, typeof(NotFoundResult)); + + if (response != null) + { + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); + } + else + { + Assert.Fail($"Response is null"); + } + } + + [TestMethod] + public async Task DeleteRoleByGuidAsync_Exception() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + var guid = Guid.NewGuid().ToString(); + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ThrowsAsync(new Exception("Unexpected error")); + ObjectResult response = (ObjectResult)await _userController.DeleteUserByGuidAsync(guid); + + Assert.IsInstanceOfType(response, typeof(ObjectResult)); + + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response is null"); + } + } + + #endregion + + #region "UPDATE" + + [TestMethod] + public async Task UpdateUserAsync_Should_Return_200_When_Successful() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + + UpdateUserRequest request = new UpdateUserRequest() + { + Data = new UpdateUserRequestData() + { + FirstName = "NewFirstName", + LastName = "NewLastName" + } + }; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserAsync(It.IsAny(), It.IsAny())).ReturnsAsync(user); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserAsync(request, user.Guid); + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status200OK, result.Status); + Assert.IsInstanceOfType(result.Data, typeof(UserDto)); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response value is null"); + } + } + + [TestMethod] + public async Task UpdateUserAsync_UserNotFound() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = null; + + UpdateUserRequest request = new UpdateUserRequest() + { + Data = new UpdateUserRequestData() + { + FirstName = "NewFirstName", + LastName = "NewLastName" + } + }; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + + NotFoundResult response = (NotFoundResult)await _userController.UpdateUserAsync(request, Guid.NewGuid().ToString()); + + if (response != null) + { + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); + } + else + { + Assert.Fail($"Response is null"); + } + } + + [TestMethod] + public async Task UpdateUserAsync_Exception() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + + UpdateUserRequest request = new UpdateUserRequest() + { + Data = new UpdateUserRequestData() + { + FirstName = "NewFirstName", + LastName = "NewLastName" + } + }; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserAsync( + It.IsAny(), It.IsAny() + )).ThrowsAsync(new Exception("Unexpected error")); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserAsync(request, user.Guid); + Assert.IsInstanceOfType(response, typeof(ObjectResult)); + + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response is null"); + } + } + + + + + + + + + + + + #endregion + + } From fa4f1c07918b7b7d9d06bf1c35c80bd4a637d3ba Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Sat, 21 Jun 2025 00:51:58 +0200 Subject: [PATCH 19/20] Added new tests --- .../Controllers/UserController_Tests.cs | 246 ++++++++++++++++++ .../Filters/ValidationActionFilter_Tests.cs | 1 - MainProject/Controllers/UserController.cs | 2 +- 3 files changed, 247 insertions(+), 2 deletions(-) diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index 1cf72ef..e79a4a1 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -648,11 +648,257 @@ public class UserController_Tests + [TestMethod] + public async Task UpdateUserPasswordAsync_Should_Return_200_When_Successful() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + + string newPassword = "This!s4T3stP4ssw0rd#"; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserPasswordAsync(It.IsAny(), newPassword)).ReturnsAsync(user); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserPasswordAsync(user.Guid, newPassword); + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status200OK, result.Status); + Assert.IsInstanceOfType(result.Data, typeof(UserDto)); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response value is null"); + } + } + + [TestMethod] + public async Task UpdateUserPasswordAsync_UserNotFound() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User? user = null; + + string newPassword = "This!s4T3stP4ssw0rd#"; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + + NotFoundResult response = (NotFoundResult)await _userController.UpdateUserPasswordAsync(Guid.NewGuid().ToString(), newPassword); + + if (response != null) + { + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); + } + else + { + Assert.Fail($"Response is null"); + } + } + + [TestMethod] + public async Task UpdateUserPasswordAsync_Exception() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + + string newPassword = "This!s4T3stP4ssw0rd#"; + + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserPasswordAsync( + It.IsAny(), It.IsAny() + )).ThrowsAsync(new Exception("Unexpected error")); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserPasswordAsync(user.Guid, newPassword); + Assert.IsInstanceOfType(response, typeof(ObjectResult)); + + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response is null"); + } + } + [TestMethod] + public async Task UpdateUserRoleAsync_Should_Return_200_When_Successful() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + if(_roleServiceMock == null) + { + Assert.Fail($"_roleServiceMock is null"); + } + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + + _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(user); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserRoleAsync(user.Guid, role.Guid); + + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status200OK, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status200OK, result.Status); + Assert.IsInstanceOfType(result.Data, typeof(UserDto)); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response value is null"); + } + } + + [TestMethod] + public async Task UpdateUserPasswordAsync_RoleNotFound() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + DatabaseSqlServer.Role? role = null; + + _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + ObjectResult response = (ObjectResult)await _userController.UpdateUserRoleAsync(user.Guid, Guid.NewGuid().ToString()); + if (response != null) + { + Assert.AreEqual(StatusCodes.Status400BadRequest, response.StatusCode); + Assert.IsNotNull(response.Value); + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status400BadRequest, result.Status); + Assert.AreEqual("Role not found", result.Message); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response is null"); + } + } + + [TestMethod] + public async Task UpdateUserRoleAsync_UserNotFound() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User? user = null; + DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + + _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(user); + + NotFoundResult response = (NotFoundResult)await _userController.UpdateUserRoleAsync(Guid.NewGuid().ToString(), role.Guid); + + if (response != null) + { + Assert.AreEqual(StatusCodes.Status404NotFound, response.StatusCode); + } + else + { + Assert.Fail($"Response is null"); + } + } + + [TestMethod] + public async Task UpdateUserRoleAsync_Exception() + { + if (_userController == null) + { + Assert.Fail($"_userController is null"); + } + + DatabaseSqlServer.User user = ModelsInit.CreateUser(); + DatabaseSqlServer.Role role = ModelsInit.CreateRole(); + + _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); + _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); + _userServiceMock?.Setup(s => s.UpdateUserPasswordAsync( + It.IsAny(), It.IsAny() + )).ThrowsAsync(new Exception("Unexpected error")); + + ObjectResult response = (ObjectResult)await _userController.UpdateUserPasswordAsync(user.Guid, role.Guid); + Assert.IsInstanceOfType(response, typeof(ObjectResult)); + + if (response != null && response.Value != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, response.StatusCode); + + var result = (BaseResponse)response.Value; + if (result != null) + { + Assert.AreEqual(StatusCodes.Status500InternalServerError, result.Status); + Assert.AreEqual("Something went wrong. Unexpected error", result.Message); + } + else + { + Assert.Fail($"Result value is null"); + } + } + else + { + Assert.Fail($"Response is null"); + } + } #endregion diff --git a/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs b/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs index b2c1f24..a09f70a 100644 --- a/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs +++ b/MainProject.Tests/Core/Filters/ValidationActionFilter_Tests.cs @@ -98,7 +98,6 @@ public class ValidationActionFilter_Tests Assert.IsNotNull(badRequestResult!.Value); ValidationError validationError = (ValidationError)badRequestResult.Value; - Console.WriteLine(JsonConvert.SerializeObject(validationError)); Assert.AreEqual(_requestNotWellFormedMessage, validationError?.Message); Assert.IsNull(validationError?.Errors); Assert.IsTrue(modelState.IsValid); diff --git a/MainProject/Controllers/UserController.cs b/MainProject/Controllers/UserController.cs index 89b0967..48d8405 100644 --- a/MainProject/Controllers/UserController.cs +++ b/MainProject/Controllers/UserController.cs @@ -168,7 +168,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers { try { - var role = await this._roleService.GetRoleForUser(roleGuid); + var role = await this._roleService.GetRoleByGuidAsync(roleGuid); if (role == null) { return BadRequest("Role not found"); From 87adaffa3e7f406d4cdd0f8a115c21b25c36bf0d Mon Sep 17 00:00:00 2001 From: csimonapastore Date: Sat, 21 Jun 2025 01:00:21 +0200 Subject: [PATCH 20/20] Minor fixes for sonarcloud --- MainProject.Tests/Controllers/UserController_Tests.cs | 8 ++++---- MainProject/Models/Api/Base/ValidationError.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MainProject.Tests/Controllers/UserController_Tests.cs b/MainProject.Tests/Controllers/UserController_Tests.cs index e79a4a1..44dbd35 100644 --- a/MainProject.Tests/Controllers/UserController_Tests.cs +++ b/MainProject.Tests/Controllers/UserController_Tests.cs @@ -572,7 +572,7 @@ public class UserController_Tests Assert.Fail($"_userController is null"); } - DatabaseSqlServer.User user = null; + DatabaseSqlServer.User? user = null; UpdateUserRequest request = new UpdateUserRequest() { @@ -872,11 +872,11 @@ public class UserController_Tests _roleServiceMock?.Setup(s => s.GetRoleByGuidAsync(It.IsAny())).ReturnsAsync(role); _userServiceMock?.Setup(s => s.GetUserByGuidAsync(It.IsAny())).ReturnsAsync(user); - _userServiceMock?.Setup(s => s.UpdateUserPasswordAsync( - It.IsAny(), It.IsAny() + _userServiceMock?.Setup(s => s.UpdateUserRoleAsync( + It.IsAny(), It.IsAny() )).ThrowsAsync(new Exception("Unexpected error")); - ObjectResult response = (ObjectResult)await _userController.UpdateUserPasswordAsync(user.Guid, role.Guid); + ObjectResult response = (ObjectResult)await _userController.UpdateUserRoleAsync(user.Guid, role.Guid); Assert.IsInstanceOfType(response, typeof(ObjectResult)); if (response != null && response.Value != null) diff --git a/MainProject/Models/Api/Base/ValidationError.cs b/MainProject/Models/Api/Base/ValidationError.cs index c0d76d6..ab96f25 100644 --- a/MainProject/Models/Api/Base/ValidationError.cs +++ b/MainProject/Models/Api/Base/ValidationError.cs @@ -4,6 +4,6 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Base; public class ValidationError { - public string Message { get; set; } - public Dictionary> Errors { get; set; } + public string? Message { get; set; } + public Dictionary>? Errors { get; set; } }