Adding role creation during startup + minor fixes in tests

This commit is contained in:
2025-03-16 22:41:44 +01:00
parent 7f5178883d
commit 18e713153b
48 changed files with 1449 additions and 340 deletions

View File

@@ -20,6 +20,7 @@ using BasicDotnetTemplate.MainProject.Models.Api.Common.User;
using BasicDotnetTemplate.MainProject.Models.Api.Common.Role; using BasicDotnetTemplate.MainProject.Models.Api.Common.Role;
using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -52,34 +53,20 @@ public class AuthController_Tests
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var authServiceMock = new Mock<IAuthService>(); var authServiceMock = new Mock<IAuthService>();
var controller = new AuthController(configuration, authServiceMock.Object); var controller = new AuthController(configuration, authServiceMock.Object);
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Username = "test",
FirstName = "test",
LastName = "test",
Email = "test",
PasswordHash = "test",
PasswordSalt = "test",
Password = "test",
Role = new DatabaseSqlServer.Role()
{
Name = "test"
},
IsTestUser = true
};
AuthenticatedUser authenticatedUser = new AuthenticatedUser(user); AuthenticatedUser authenticatedUser = new AuthenticatedUser(user);
var request = new AuthenticateRequest { Data = new AuthenticateRequestData { Username = "user", Password = "pass" } }; var request = new AuthenticateRequest { Data = new AuthenticateRequestData { Email = "user", Password = "pass" } };
authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny<AuthenticateRequestData>())).ReturnsAsync(authenticatedUser); authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny<AuthenticateRequestData>())).ReturnsAsync(authenticatedUser);
ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request)); ObjectResult response = (ObjectResult)(await controller.AuthenticateAsync(request));
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 200); Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 200); Assert.IsTrue(result.Status == StatusCodes.Status200OK);
Assert.IsInstanceOfType(result.Data, typeof(AuthenticatedUser)); Assert.IsInstanceOfType(result.Data, typeof(AuthenticatedUser));
} }
else else
@@ -111,12 +98,12 @@ public class AuthController_Tests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 400); Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 400); Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest);
Assert.IsTrue(result.Message == "Request is not well formed"); Assert.IsTrue(result.Message == "Request is not well formed");
} }
else else
@@ -141,8 +128,8 @@ public class AuthController_Tests
{ {
Data = new AuthenticateRequestData() Data = new AuthenticateRequestData()
{ {
Username = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7", Email = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=",
Password = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7" Password = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A="
} }
}; };
AuthenticatedUser? authenticatedUser = null; AuthenticatedUser? authenticatedUser = null;
@@ -153,7 +140,7 @@ public class AuthController_Tests
if (response != null) if (response != null)
{ {
Assert.IsTrue(response.StatusCode == 404); Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound);
} }
else else
{ {
@@ -181,12 +168,12 @@ public class AuthController_Tests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 400); Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 400); Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest);
Assert.IsTrue(result.Message == "Request is not well formed"); Assert.IsTrue(result.Message == "Request is not well formed");
} }
else else
@@ -209,7 +196,7 @@ public class AuthController_Tests
var request = new AuthenticateRequest var request = new AuthenticateRequest
{ {
Data = new AuthenticateRequestData { Username = "user", Password = "pass" } Data = new AuthenticateRequestData { Email = "user", Password = "pass" }
}; };
authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny<AuthenticateRequestData>())).ThrowsAsync(new Exception("Unexpected error")); authServiceMock.Setup(s => s.AuthenticateAsync(It.IsAny<AuthenticateRequestData>())).ThrowsAsync(new Exception("Unexpected error"));
@@ -220,12 +207,12 @@ public class AuthController_Tests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 500); Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 500); Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError);
Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); Assert.IsTrue(result.Message == "Something went wrong. Unexpected error");
} }
else else

View File

@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -29,7 +30,7 @@ public class RootController_Test
if (result != null) if (result != null)
{ {
var data = (OkResult)result; var data = (OkResult)result;
Assert.IsTrue(data.StatusCode == 200); Assert.IsTrue(data.StatusCode == StatusCodes.Status200OK);
} }
else else
{ {
@@ -39,7 +40,7 @@ public class RootController_Test
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -22,6 +22,7 @@ using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlSer
using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth;
using AutoMapper; using AutoMapper;
using BasicDotnetTemplate.MainProject.Core.Middlewares; using BasicDotnetTemplate.MainProject.Core.Middlewares;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -50,7 +51,8 @@ public class UserControllerTests
try try
{ {
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
_ = new UserController(null, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
_ = new UserController(null, userServiceMock.Object, roleServiceMock.Object);
exception = false; exception = false;
Assert.Fail($"This test should not pass as configuration is null"); Assert.Fail($"This test should not pass as configuration is null");
} }
@@ -66,35 +68,21 @@ public class UserControllerTests
{ {
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
var controller = new UserController(configuration, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
var controller = new UserController(configuration, userServiceMock.Object, roleServiceMock.Object);
var guid = Guid.NewGuid().ToString(); var guid = Guid.NewGuid().ToString();
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Guid = guid,
Username = "Username",
FirstName = "FirstName",
LastName = "LastName",
Email = "Email",
PasswordHash = "PasswordHash",
PasswordSalt = "PasswordSalt",
Password = "Password",
Role = new DatabaseSqlServer.Role()
{
Name = "Role.Name"
},
IsTestUser = true
};
userServiceMock.Setup(s => s.GetUserByGuidAsync(It.IsAny<string>())).ReturnsAsync(user); userServiceMock.Setup(s => s.GetUserByGuidAsync(It.IsAny<string>())).ReturnsAsync(user);
ObjectResult response = (ObjectResult)(await controller.GetUserByGuidAsync(guid)); ObjectResult response = (ObjectResult)(await controller.GetUserByGuidAsync(guid));
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 200); Assert.IsTrue(response.StatusCode == StatusCodes.Status200OK);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 200); Assert.IsTrue(result.Status == StatusCodes.Status200OK);
Assert.IsInstanceOfType(result.Data, typeof(DatabaseSqlServer.User)); Assert.IsInstanceOfType(result.Data, typeof(DatabaseSqlServer.User));
} }
else else
@@ -113,7 +101,8 @@ public class UserControllerTests
{ {
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
var controller = new UserController(configuration, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
var controller = new UserController(configuration, userServiceMock.Object, roleServiceMock.Object);
var guid = String.Empty; var guid = String.Empty;
DatabaseSqlServer.User? user = null; DatabaseSqlServer.User? user = null;
@@ -123,12 +112,12 @@ public class UserControllerTests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 400); Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 400); Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest);
Assert.IsTrue(result.Message == "Request is not well formed"); Assert.IsTrue(result.Message == "Request is not well formed");
} }
else else
@@ -147,7 +136,8 @@ public class UserControllerTests
{ {
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
var controller = new UserController(configuration, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
var controller = new UserController(configuration, userServiceMock.Object, roleServiceMock.Object);
var guid = Guid.NewGuid().ToString(); var guid = Guid.NewGuid().ToString();
DatabaseSqlServer.User? user = null; DatabaseSqlServer.User? user = null;
@@ -158,7 +148,7 @@ public class UserControllerTests
if (response != null) if (response != null)
{ {
Assert.IsTrue(response.StatusCode == 404); Assert.IsTrue(response.StatusCode == StatusCodes.Status404NotFound);
} }
else else
{ {
@@ -171,7 +161,8 @@ public class UserControllerTests
{ {
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
var controller = new UserController(configuration, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
var controller = new UserController(configuration, userServiceMock.Object, roleServiceMock.Object);
var guid = Guid.NewGuid().ToString(); var guid = Guid.NewGuid().ToString();
DatabaseSqlServer.User? user = null; DatabaseSqlServer.User? user = null;
@@ -183,12 +174,12 @@ public class UserControllerTests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 400); Assert.IsTrue(response.StatusCode == StatusCodes.Status400BadRequest);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 400); Assert.IsTrue(result.Status == StatusCodes.Status400BadRequest);
Assert.IsTrue(result.Message == "Request is not well formed"); Assert.IsTrue(result.Message == "Request is not well formed");
} }
else else
@@ -207,7 +198,8 @@ public class UserControllerTests
{ {
IConfiguration configuration = TestUtils.CreateConfiguration(); IConfiguration configuration = TestUtils.CreateConfiguration();
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
var controller = new UserController(configuration, userServiceMock.Object); var roleServiceMock = new Mock<IRoleService>();
var controller = new UserController(configuration, userServiceMock.Object, roleServiceMock.Object);
var guid = Guid.NewGuid().ToString(); var guid = Guid.NewGuid().ToString();
userServiceMock.Setup(s => s.GetUserByGuidAsync(It.IsAny<string>())).ThrowsAsync(new Exception("Unexpected error")); userServiceMock.Setup(s => s.GetUserByGuidAsync(It.IsAny<string>())).ThrowsAsync(new Exception("Unexpected error"));
@@ -217,12 +209,12 @@ public class UserControllerTests
if (response != null && response.Value != null) if (response != null && response.Value != null)
{ {
Assert.IsTrue(response.StatusCode == 500); Assert.IsTrue(response.StatusCode == StatusCodes.Status500InternalServerError);
var result = (BaseResponse<object>)response.Value; var result = (BaseResponse<object>)response.Value;
if (result != null) if (result != null)
{ {
Assert.IsTrue(result.Status == 500); Assert.IsTrue(result.Status == StatusCodes.Status500InternalServerError);
Assert.IsTrue(result.Message == "Something went wrong. Unexpected error"); Assert.IsTrue(result.Message == "Something went wrong. Unexpected error");
} }
else else

View File

@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -53,7 +54,7 @@ public class VersionController_Tests
AppSettings appSettings = new AppSettings(); AppSettings appSettings = new AppSettings();
configuration.GetSection("AppSettings").Bind(appSettings); configuration.GetSection("AppSettings").Bind(appSettings);
string version = data.Data != null ? (string)data.Data : ""; string version = data.Data != null ? (string)data.Data : "";
Assert.IsTrue((((IStatusCodeActionResult)result).StatusCode == 200) && (version == appSettings.Settings?.Version)); Assert.IsTrue((((IStatusCodeActionResult)result).StatusCode == StatusCodes.Status200OK) && (version == appSettings.Settings?.Version));
} }
else else
{ {
@@ -68,7 +69,7 @@ public class VersionController_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -87,7 +88,7 @@ public class VersionController_Tests
if (objectResult != null) if (objectResult != null)
{ {
var data = (BaseResponse<object>)objectResult; var data = (BaseResponse<object>)objectResult;
Assert.IsTrue((((IStatusCodeActionResult)result).StatusCode == 200) && String.IsNullOrEmpty(data.Data)); Assert.IsTrue((((IStatusCodeActionResult)result).StatusCode == StatusCodes.Status200OK) && String.IsNullOrEmpty(data.Data));
} }
else else
{ {
@@ -97,7 +98,7 @@ public class VersionController_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -30,22 +30,7 @@ public class JwtAuthorizationAttribute_Tests
{ {
_attribute = new JwtAuthorizationAttribute(); _attribute = new JwtAuthorizationAttribute();
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Guid = Guid.NewGuid().ToString(),
Username = "Username",
FirstName = "FirstName",
LastName = "LastName",
Email = "Email",
PasswordHash = "PasswordHash",
PasswordSalt = "PasswordSalt",
Password = "Password",
Role = new DatabaseSqlServer.Role()
{
Name = "Role.Name"
},
IsTestUser = true
};
_authenticatedUser = new AuthenticatedUser(user); _authenticatedUser = new AuthenticatedUser(user);
WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>()); WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>());
@@ -89,7 +74,7 @@ public class JwtAuthorizationAttribute_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -37,26 +37,10 @@ public class AutoMapperConfiguration_Tests
{ {
try try
{ {
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Guid = Guid.NewGuid().ToString(),
Username = "Username",
FirstName = "FirstName",
LastName = "LastName",
Email = "Email",
PasswordHash = "PasswordHash",
PasswordSalt = "PasswordSalt",
Password = "Password",
Role = new DatabaseSqlServer.Role()
{
Name = "Role.Name"
},
IsTestUser = true
};
UserDto? data = _mapper?.Map<UserDto>(user); UserDto? data = _mapper?.Map<UserDto>(user);
Assert.IsTrue(data?.Guid == user.Guid); Assert.IsTrue(data?.Guid == user.Guid);
Assert.IsTrue(data?.Username == user.Username);
Assert.IsTrue(data?.FirstName == user.FirstName); Assert.IsTrue(data?.FirstName == user.FirstName);
Assert.IsTrue(data?.LastName == user.LastName); Assert.IsTrue(data?.LastName == user.LastName);
Assert.IsTrue(data?.Email == user.Email); Assert.IsTrue(data?.Email == user.Email);
@@ -64,7 +48,7 @@ public class AutoMapperConfiguration_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -22,10 +22,7 @@ public class UserRole_Tests
{ {
try try
{ {
DatabaseSqlServer.Role role = new DatabaseSqlServer.Role() DatabaseSqlServer.Role role = ModelsInit.CreateRole();
{
Name = "test"
};
UserRole userRole = new UserRole(role); UserRole userRole = new UserRole(role);
Assert.IsTrue(userRole.Name == role.Name); Assert.IsTrue(userRole.Name == role.Name);
@@ -33,7 +30,7 @@ public class UserRole_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -22,24 +22,9 @@ public class AuthenticatedUser_Tests
{ {
try try
{ {
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Username = "test",
FirstName = "test",
LastName = "test",
Email = "test",
PasswordHash = "test",
PasswordSalt = "test",
Password = "test",
Role = new DatabaseSqlServer.Role()
{
Name = "test"
},
IsTestUser = true
};
AuthenticatedUser authenticatedUser = new AuthenticatedUser(user); AuthenticatedUser authenticatedUser = new AuthenticatedUser(user);
Assert.IsTrue(authenticatedUser.Username == user.Username);
Assert.IsTrue(authenticatedUser.FirstName == user.FirstName); Assert.IsTrue(authenticatedUser.FirstName == user.FirstName);
Assert.IsTrue(authenticatedUser.LastName == user.LastName); Assert.IsTrue(authenticatedUser.LastName == user.LastName);
Assert.IsTrue(authenticatedUser.Email == user.Email); Assert.IsTrue(authenticatedUser.Email == user.Email);
@@ -48,7 +33,7 @@ public class AuthenticatedUser_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
using BasicDotnetTemplate.MainProject; using BasicDotnetTemplate.MainProject;
using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response;
using Microsoft.Extensions.DependencyModel.Resolution; using Microsoft.Extensions.DependencyModel.Resolution;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -19,12 +20,12 @@ public class ApiResponse_Tests
try try
{ {
var baseResponse = new BaseResponse<object>(200, null, null); var baseResponse = new BaseResponse<object>(200, null, null);
Assert.IsTrue(baseResponse.Status == 200 && String.IsNullOrEmpty(baseResponse.Message) && baseResponse.Data == null); Assert.IsTrue(baseResponse.Status == StatusCodes.Status200OK && String.IsNullOrEmpty(baseResponse.Message) && baseResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -34,12 +35,12 @@ public class ApiResponse_Tests
try try
{ {
var baseResponse = new BaseResponse<object>(201, null, null); var baseResponse = new BaseResponse<object>(201, null, null);
Assert.IsFalse(baseResponse.Status == 200); Assert.IsFalse(baseResponse.Status == StatusCodes.Status200OK);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -49,12 +50,12 @@ public class ApiResponse_Tests
try try
{ {
var baseResponse = new BaseResponse<object>(200, "This is a test message", null); var baseResponse = new BaseResponse<object>(200, "This is a test message", null);
Assert.IsTrue(baseResponse.Status == 200 && baseResponse.Message == "This is a test message" && baseResponse.Data == null); Assert.IsTrue(baseResponse.Status == StatusCodes.Status200OK && baseResponse.Message == "This is a test message" && baseResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -65,12 +66,12 @@ public class ApiResponse_Tests
{ {
string[] data = { "Volvo", "BMW", "Ford", "Mazda" }; string[] data = { "Volvo", "BMW", "Ford", "Mazda" };
var baseResponse = new BaseResponse<string[]>(200, "This is a test message", data); var baseResponse = new BaseResponse<string[]>(200, "This is a test message", data);
Assert.IsTrue(baseResponse.Status == 200 && baseResponse.Message == "This is a test message" && baseResponse.Data == data); Assert.IsTrue(baseResponse.Status == StatusCodes.Status200OK && baseResponse.Message == "This is a test message" && baseResponse.Data == data);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -10,6 +10,7 @@ using BasicDotnetTemplate.MainProject.Models.Api.Common.User;
using BasicDotnetTemplate.MainProject.Models.Api.Common.Role; using BasicDotnetTemplate.MainProject.Models.Api.Common.Role;
using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -23,12 +24,12 @@ public class AuthenticateResponse_Tests
try try
{ {
var authenticateResponse = new AuthenticateResponse(200, null, null); var authenticateResponse = new AuthenticateResponse(200, null, null);
Assert.IsTrue(authenticateResponse.Status == 200 && String.IsNullOrEmpty(authenticateResponse.Message) && authenticateResponse.Data == null); Assert.IsTrue(authenticateResponse.Status == StatusCodes.Status200OK && String.IsNullOrEmpty(authenticateResponse.Message) && authenticateResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -38,12 +39,12 @@ public class AuthenticateResponse_Tests
try try
{ {
var authenticateResponse = new AuthenticateResponse(201, null, null); var authenticateResponse = new AuthenticateResponse(201, null, null);
Assert.IsFalse(authenticateResponse.Status == 200); Assert.IsFalse(authenticateResponse.Status == StatusCodes.Status200OK);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -53,12 +54,12 @@ public class AuthenticateResponse_Tests
try try
{ {
var authenticateResponse = new AuthenticateResponse(200, "This is a test message", null); var authenticateResponse = new AuthenticateResponse(200, "This is a test message", null);
Assert.IsTrue(authenticateResponse.Status == 200 && authenticateResponse.Message == "This is a test message" && authenticateResponse.Data == null); Assert.IsTrue(authenticateResponse.Status == StatusCodes.Status200OK && authenticateResponse.Message == "This is a test message" && authenticateResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -67,29 +68,15 @@ public class AuthenticateResponse_Tests
{ {
try try
{ {
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Username = "test",
FirstName = "test",
LastName = "test",
Email = "test",
PasswordHash = "test",
PasswordSalt = "test",
Password = "test",
Role = new DatabaseSqlServer.Role()
{
Name = "test"
},
IsTestUser = true
};
AuthenticatedUser data = new AuthenticatedUser(user); AuthenticatedUser data = new AuthenticatedUser(user);
var authenticateResponse = new AuthenticateResponse(200, "This is a test message", data); var authenticateResponse = new AuthenticateResponse(200, "This is a test message", data);
Assert.IsTrue(authenticateResponse.Status == 200 && authenticateResponse.Message == "This is a test message" && authenticateResponse.Data == data); Assert.IsTrue(authenticateResponse.Status == StatusCodes.Status200OK && authenticateResponse.Message == "This is a test message" && authenticateResponse.Data == data);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -12,6 +12,7 @@ using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlSer
using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth; using BasicDotnetTemplate.MainProject.Models.Api.Response.Auth;
using BasicDotnetTemplate.MainProject.Core.Middlewares; using BasicDotnetTemplate.MainProject.Core.Middlewares;
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -38,12 +39,12 @@ public class GetUserResponse_Tests
try try
{ {
var getUserResponse = new GetUserResponse(200, null, null); var getUserResponse = new GetUserResponse(200, null, null);
Assert.IsTrue(getUserResponse.Status == 200 && String.IsNullOrEmpty(getUserResponse.Message) && getUserResponse.Data == null); Assert.IsTrue(getUserResponse.Status == StatusCodes.Status200OK && String.IsNullOrEmpty(getUserResponse.Message) && getUserResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -53,12 +54,12 @@ public class GetUserResponse_Tests
try try
{ {
var getUserResponse = new GetUserResponse(201, null, null); var getUserResponse = new GetUserResponse(201, null, null);
Assert.IsFalse(getUserResponse.Status == 200); Assert.IsFalse(getUserResponse.Status == StatusCodes.Status200OK);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -68,12 +69,12 @@ public class GetUserResponse_Tests
try try
{ {
var getUserResponse = new GetUserResponse(200, "This is a test message", null); var getUserResponse = new GetUserResponse(200, "This is a test message", null);
Assert.IsTrue(getUserResponse.Status == 200 && getUserResponse.Message == "This is a test message" && getUserResponse.Data == null); Assert.IsTrue(getUserResponse.Status == StatusCodes.Status200OK && getUserResponse.Message == "This is a test message" && getUserResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -82,29 +83,15 @@ public class GetUserResponse_Tests
{ {
try try
{ {
DatabaseSqlServer.User user = new DatabaseSqlServer.User() DatabaseSqlServer.User user = ModelsInit.CreateUser();
{
Username = "test",
FirstName = "test",
LastName = "test",
Email = "test",
PasswordHash = "test",
PasswordSalt = "test",
Password = "test",
Role = new DatabaseSqlServer.Role()
{
Name = "test"
},
IsTestUser = true
};
UserDto? data = _mapper?.Map<UserDto>(user); UserDto? data = _mapper?.Map<UserDto>(user);
var getUserResponse = new GetUserResponse(200, "This is a test message", data); var getUserResponse = new GetUserResponse(200, "This is a test message", data);
Assert.IsTrue(getUserResponse.Status == 200 && getUserResponse.Message == "This is a test message" && getUserResponse.Data == data); Assert.IsTrue(getUserResponse.Status == StatusCodes.Status200OK && getUserResponse.Message == "This is a test message" && getUserResponse.Data == data);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -7,6 +7,7 @@ using BasicDotnetTemplate.MainProject;
using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response;
using Microsoft.Extensions.DependencyModel.Resolution; using Microsoft.Extensions.DependencyModel.Resolution;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -43,7 +44,7 @@ public class Settings_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -53,12 +54,12 @@ public class Settings_Tests
try try
{ {
var baseResponse = new BaseResponse<object>(201, null, null); var baseResponse = new BaseResponse<object>(201, null, null);
Assert.IsFalse(baseResponse.Status == 200); Assert.IsFalse(baseResponse.Status == StatusCodes.Status200OK);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -68,12 +69,12 @@ public class Settings_Tests
try try
{ {
var baseResponse = new BaseResponse<object>(200, "This is a test message", null); var baseResponse = new BaseResponse<object>(200, "This is a test message", null);
Assert.IsTrue(baseResponse.Status == 200 && baseResponse.Message == "This is a test message" && baseResponse.Data == null); Assert.IsTrue(baseResponse.Status == StatusCodes.Status200OK && baseResponse.Message == "This is a test message" && baseResponse.Data == null);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -84,12 +85,12 @@ public class Settings_Tests
{ {
string[] data = { "Volvo", "BMW", "Ford", "Mazda" }; string[] data = { "Volvo", "BMW", "Ford", "Mazda" };
var baseResponse = new BaseResponse<string[]>(200, "This is a test message", data); var baseResponse = new BaseResponse<string[]>(200, "This is a test message", data);
Assert.IsTrue(baseResponse.Status == 200 && baseResponse.Message == "This is a test message" && baseResponse.Data == data); Assert.IsTrue(baseResponse.Status == StatusCodes.Status200OK && baseResponse.Message == "This is a test message" && baseResponse.Data == data);
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
} }

View File

@@ -70,7 +70,7 @@ public class Program_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -29,7 +29,7 @@ public class AuthService_Tests
try try
{ {
var authService = TestUtils.CreateAuthService(); var authService = TestUtils.CreateAuthService();
if(authService != null) if (authService != null)
{ {
Assert.IsInstanceOfType(authService, typeof(AuthService)); Assert.IsInstanceOfType(authService, typeof(AuthService));
} }
@@ -41,7 +41,7 @@ public class AuthService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -54,12 +54,12 @@ public class AuthService_Tests
{ {
Data = new AuthenticateRequestData Data = new AuthenticateRequestData
{ {
Username = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=", Email = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=",
Password = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=" Password = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A="
} }
}; };
var authService = TestUtils.CreateAuthService(); var authService = TestUtils.CreateAuthService();
if(authService != null) if (authService != null)
{ {
var authenticatedUser = await authService.AuthenticateAsync(request.Data); var authenticatedUser = await authService.AuthenticateAsync(request.Data);
Assert.IsTrue(authenticatedUser == null); Assert.IsTrue(authenticatedUser == null);
@@ -72,21 +72,10 @@ public class AuthService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
// if(authenticatedUser == null)
// {
// Console.WriteLine(JsonConvert.SerializeObject(authenticatedUser));
// Assert.IsTrue(authenticatedUser.Username == expectedAuthenticatedUser.Username);
// }
// else
// {
// Console.WriteLine(JsonConvert.SerializeObject(authenticatedUser));
// Assert.Fail($"authenticatedUser is null");
// }
[TestMethod] [TestMethod]
public async Task AuthenticateAsync_UsernamePasswordInvalid() public async Task AuthenticateAsync_UsernamePasswordInvalid()
{ {
@@ -96,12 +85,12 @@ public class AuthService_Tests
{ {
Data = new AuthenticateRequestData Data = new AuthenticateRequestData
{ {
Username = "WGHWRBE5mVWaV=", Email = "WGHWRBE5mVWaV=",
Password = "WGHWRBE5mVWaV=" Password = "WGHWRBE5mVWaV="
} }
}; };
var authService = TestUtils.CreateAuthService(); var authService = TestUtils.CreateAuthService();
if(authService != null) if (authService != null)
{ {
var authenticatedUser = await authService.AuthenticateAsync(request.Data); var authenticatedUser = await authService.AuthenticateAsync(request.Data);
Assert.IsTrue(authenticatedUser == null); Assert.IsTrue(authenticatedUser == null);
@@ -114,7 +103,7 @@ public class AuthService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -39,7 +39,7 @@ public class JwtService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -64,7 +64,7 @@ public class JwtService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -29,7 +29,7 @@ public class UserService_Tests
try try
{ {
var userService = TestUtils.CreateUserService(); var userService = TestUtils.CreateUserService();
if(userService != null) if (userService != null)
{ {
Assert.IsInstanceOfType(userService, typeof(UserService)); Assert.IsInstanceOfType(userService, typeof(UserService));
} }
@@ -41,7 +41,7 @@ public class UserService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -52,7 +52,7 @@ public class UserService_Tests
{ {
var userService = TestUtils.CreateUserService(); var userService = TestUtils.CreateUserService();
var testString = "test"; var testString = "test";
if(userService != null) if (userService != null)
{ {
var user = await userService.GetUserByUsernameAndPassword(testString, testString); var user = await userService.GetUserByUsernameAndPassword(testString, testString);
Assert.IsTrue(user == null); Assert.IsTrue(user == null);
@@ -65,7 +65,7 @@ public class UserService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -76,13 +76,13 @@ public class UserService_Tests
try try
{ {
var userService = TestUtils.CreateUserService(); var userService = TestUtils.CreateUserService();
var testUsername = "test@email.it"; var testEmail = "test@email.it";
var testPassword = "password"; var testPassword = "password";
if(userService != null) if (userService != null)
{ {
var user = await userService.GetUserByUsernameAndPassword(testUsername, testPassword); var user = await userService.GetUserByUsernameAndPassword(testEmail, testPassword);
Assert.IsTrue(user != null); Assert.IsTrue(user != null);
Assert.IsTrue(user.Username == testUsername); Assert.IsTrue(user.Email == testEmail);
} }
else else
{ {
@@ -92,7 +92,7 @@ public class UserService_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -0,0 +1,35 @@
using DatabaseSqlServer = BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
namespace BasicDotnetTemplate.MainProject.Tests;
public static class ModelsInit
{
public static DatabaseSqlServer.User CreateUser()
{
DatabaseSqlServer.User user = new DatabaseSqlServer.User()
{
Guid = Guid.NewGuid().ToString(),
FirstName = "FirstName",
LastName = "LastName",
Email = "Email",
PasswordHash = "PasswordHash",
PasswordSalt = "PasswordSalt",
Password = "Password",
Role = CreateRole(),
IsTestUser = true
};
return user;
}
public static DatabaseSqlServer.Role CreateRole()
{
DatabaseSqlServer.Role role = new DatabaseSqlServer.Role()
{
Guid = Guid.NewGuid().ToString(),
Name = "Name",
IsNotEditable = false
};
return role;
}
}

View File

@@ -17,6 +17,7 @@ using Microsoft.EntityFrameworkCore;
using Moq; using Moq;
using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Services; using BasicDotnetTemplate.MainProject.Services;
using Microsoft.AspNetCore.Http;
namespace BasicDotnetTemplate.MainProject.Tests; namespace BasicDotnetTemplate.MainProject.Tests;
@@ -43,33 +44,42 @@ public static class TestUtils
.Build(); .Build();
} }
public static string GetSqlConnectionString(IConfiguration configuration)
{
AppSettings _appSettings = new AppSettings();
configuration.GetSection("AppSettings").Bind(_appSettings);
return _appSettings.DatabaseSettings?.SqlServerConnectionString ?? String.Empty;
}
public static AuthService CreateAuthService() public static AuthService CreateAuthService()
{ {
IConfiguration configuration = CreateConfiguration(); IConfiguration configuration = CreateConfiguration();
var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>(); var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>();
optionsBuilder.UseSqlServer("test"); optionsBuilder.UseSqlServer(GetSqlConnectionString(configuration));
SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options); SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options);
var userServiceMock = new Mock<IUserService>(); var userServiceMock = new Mock<IUserService>();
return new AuthService(configuration, sqlServerContext, userServiceMock.Object); var httpContextAccessor = new Mock<IHttpContextAccessor>();
return new AuthService(httpContextAccessor.Object, configuration, sqlServerContext, userServiceMock.Object);
} }
public static UserService CreateUserService() public static UserService CreateUserService()
{ {
IConfiguration configuration = CreateConfiguration(); IConfiguration configuration = CreateConfiguration();
var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>(); var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>();
optionsBuilder.UseSqlServer("test"); optionsBuilder.UseSqlServer(GetSqlConnectionString(configuration));
SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options); SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options);
return new UserService(configuration, sqlServerContext); var httpContextAccessor = new Mock<IHttpContextAccessor>();
return new UserService(httpContextAccessor.Object, configuration, sqlServerContext);
} }
public static JwtService CreateJwtService() public static JwtService CreateJwtService()
{ {
IConfiguration configuration = CreateConfiguration(); IConfiguration configuration = CreateConfiguration();
var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>(); var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>();
optionsBuilder.UseSqlServer("test"); optionsBuilder.UseSqlServer(GetSqlConnectionString(configuration));
SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options); SqlServerContext sqlServerContext = new SqlServerContext(optionsBuilder.Options);
var userServiceMock = new Mock<IUserService>(); var httpContextAccessor = new Mock<IHttpContextAccessor>();
return new JwtService(configuration, sqlServerContext, userServiceMock.Object); return new JwtService(httpContextAccessor.Object, configuration, sqlServerContext);
} }
} }

View File

@@ -27,7 +27,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -47,7 +47,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -77,7 +77,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -97,7 +97,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -112,7 +112,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -134,7 +134,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -158,7 +158,7 @@ public class CryptoUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -27,7 +27,7 @@ public class JwtTokenUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -46,7 +46,7 @@ public class JwtTokenUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -65,7 +65,7 @@ public class JwtTokenUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -44,7 +44,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -80,7 +80,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -97,7 +97,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -126,7 +126,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -160,7 +160,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -196,7 +196,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -220,7 +220,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -240,7 +240,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -260,7 +260,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -280,7 +280,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }
@@ -305,7 +305,7 @@ public class ProgramUtils_Tests
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.InnerException); Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}"); Assert.Fail($"An exception was thrown: {ex}");
} }
} }

View File

@@ -32,17 +32,17 @@ namespace BasicDotnetTemplate.MainProject.Controllers
{ {
if (!ModelState.IsValid) if (!ModelState.IsValid)
{ {
return BadRequest("Request is not well formed"); return BadRequest(_requestNotWellFormed);
} }
if ( if (
request == null || request == null ||
request.Data == null || request.Data == null ||
String.IsNullOrEmpty(request.Data.Username) || String.IsNullOrEmpty(request.Data.Email) ||
String.IsNullOrEmpty(request.Data.Password) String.IsNullOrEmpty(request.Data.Password)
) )
{ {
return BadRequest("Request is not well formed"); return BadRequest(_requestNotWellFormed);
} }
var data = await this._authService.AuthenticateAsync(request.Data); var data = await this._authService.AuthenticateAsync(request.Data);

View File

@@ -9,6 +9,7 @@ namespace BasicDotnetTemplate.MainProject.Controllers
{ {
protected readonly IConfiguration _configuration; protected readonly IConfiguration _configuration;
protected readonly AppSettings _appSettings; protected readonly AppSettings _appSettings;
protected readonly string _requestNotWellFormed = "Request is not well formed";
protected BaseController( protected BaseController(
IConfiguration configuration IConfiguration configuration

View File

@@ -2,22 +2,27 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using BasicDotnetTemplate.MainProject.Core.Attributes; using BasicDotnetTemplate.MainProject.Core.Attributes;
using BasicDotnetTemplate.MainProject.Services; using BasicDotnetTemplate.MainProject.Services;
//using BasicDotnetTemplate.MainProject.Models.Api.Request.User; using BasicDotnetTemplate.MainProject.Models.Api.Request.User;
using BasicDotnetTemplate.MainProject.Models.Api.Response; using BasicDotnetTemplate.MainProject.Models.Api.Response;
using BasicDotnetTemplate.MainProject.Models.Api.Response.User; using BasicDotnetTemplate.MainProject.Models.Api.Response.User;
using BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
namespace BasicDotnetTemplate.MainProject.Controllers namespace BasicDotnetTemplate.MainProject.Controllers
{ {
[Route("[controller]")] [Route("[controller]")]
public class UserController : BaseController public class UserController : BaseController
{ {
private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly IRoleService _roleService;
public UserController( public UserController(
IConfiguration configuration, IConfiguration configuration,
IUserService userService IUserService userService,
IRoleService roleService
) : base(configuration) ) : base(configuration)
{ {
this._userService = userService; this._userService = userService;
this._roleService = roleService;
} }
[JwtAuthorization()] [JwtAuthorization()]
@@ -32,12 +37,12 @@ namespace BasicDotnetTemplate.MainProject.Controllers
{ {
if (!ModelState.IsValid) if (!ModelState.IsValid)
{ {
return BadRequest("Request is not well formed"); return BadRequest(_requestNotWellFormed);
} }
if (String.IsNullOrEmpty(guid)) if (String.IsNullOrEmpty(guid))
{ {
return BadRequest("Request is not well formed"); return BadRequest(_requestNotWellFormed);
} }
var data = await this._userService.GetUserByGuidAsync(guid); var data = await this._userService.GetUserByGuidAsync(guid);
@@ -59,5 +64,62 @@ namespace BasicDotnetTemplate.MainProject.Controllers
} }
} }
[JwtAuthorization()]
[HttpPost("create")]
[ProducesResponseType<GetUserResponse>(StatusCodes.Status201Created)]
[ProducesResponseType<BaseResponse<object>>(StatusCodes.Status400BadRequest)]
[ProducesResponseType<BaseResponse<object>>(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateUserAsync([FromBody] CreateUserRequest request)
{
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))
{
return BadRequest();
}
else
{
Role? role = null; // TODO
var data = await this._userService.CreateUser(request.Data, role);
if (data == null || String.IsNullOrEmpty(data.Guid))
{
return BadRequest();
}
return Success(String.Empty, data);
}
}
catch (Exception exception)
{
var message = "Something went wrong";
if (!String.IsNullOrEmpty(exception.Message))
{
message += $". {exception.Message}";
}
return InternalServerError(message);
}
}
} }
} }

View File

@@ -13,6 +13,7 @@ namespace BasicDotnetTemplate.MainProject.Core.Database
} }
public DbSet<User> Users { get; set; } public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
@@ -21,9 +22,11 @@ namespace BasicDotnetTemplate.MainProject.Core.Database
.HasIndex(x => x.Email, "IX_Email"); .HasIndex(x => x.Email, "IX_Email");
modelBuilder.Entity<User>() modelBuilder.Entity<User>()
.HasIndex(x => x.Username, "IX_Username"); .HasIndex(x => new { x.IsDeleted, x.Guid }, "IX_IsDeleted_Guid")
.HasFilter("[IsDeleted] = 0");
modelBuilder.Entity<User>()
modelBuilder.Entity<Role>()
.HasIndex(x => new { x.IsDeleted, x.Guid }, "IX_IsDeleted_Guid") .HasIndex(x => new { x.IsDeleted, x.Guid }, "IX_IsDeleted_Guid")
.HasFilter("[IsDeleted] = 0"); .HasFilter("[IsDeleted] = 0");
} }

View File

@@ -0,0 +1,167 @@
// <auto-generated />
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("20250316014620_AlterTablesUsersAndRoles")]
partial class AlterTablesUsersAndRoles
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<DateTime>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsTestUser")
.HasColumnType("bit");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordSalt")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RoleId")
.HasColumnType("int");
b.Property<DateTime>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Role");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,225 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MainProject.Migrations
{
/// <inheritdoc />
public partial class AlterTablesUsersAndRoles : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Users_Role_RoleId",
table: "Users");
migrationBuilder.DropIndex(
name: "IX_Username",
table: "Users");
migrationBuilder.DropPrimaryKey(
name: "PK_Role",
table: "Role");
migrationBuilder.DropColumn(
name: "Username",
table: "Users");
migrationBuilder.RenameTable(
name: "Role",
newName: "Roles");
migrationBuilder.AlterColumn<int>(
name: "UpdateUserId",
table: "Users",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "DeletionUserId",
table: "Users",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "CreationUserId",
table: "Users",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "UpdateUserId",
table: "Roles",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Roles",
type: "nvarchar(100)",
maxLength: 100,
nullable: false,
oldClrType: typeof(string),
oldType: "nvarchar(max)");
migrationBuilder.AlterColumn<int>(
name: "DeletionUserId",
table: "Roles",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "CreationUserId",
table: "Roles",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddPrimaryKey(
name: "PK_Roles",
table: "Roles",
column: "Id");
migrationBuilder.CreateIndex(
name: "IX_IsDeleted_Guid",
table: "Roles",
columns: new[] { "IsDeleted", "Guid" },
filter: "[IsDeleted] = 0");
migrationBuilder.AddForeignKey(
name: "FK_Users_Roles_RoleId",
table: "Users",
column: "RoleId",
principalTable: "Roles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Users_Roles_RoleId",
table: "Users");
migrationBuilder.DropPrimaryKey(
name: "PK_Roles",
table: "Roles");
migrationBuilder.DropIndex(
name: "IX_IsDeleted_Guid",
table: "Roles");
migrationBuilder.RenameTable(
name: "Roles",
newName: "Role");
migrationBuilder.AlterColumn<int>(
name: "UpdateUserId",
table: "Users",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "DeletionUserId",
table: "Users",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "CreationUserId",
table: "Users",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AddColumn<string>(
name: "Username",
table: "Users",
type: "nvarchar(200)",
maxLength: 200,
nullable: false,
defaultValue: "");
migrationBuilder.AlterColumn<int>(
name: "UpdateUserId",
table: "Role",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Role",
type: "nvarchar(max)",
nullable: false,
oldClrType: typeof(string),
oldType: "nvarchar(100)",
oldMaxLength: 100);
migrationBuilder.AlterColumn<int>(
name: "DeletionUserId",
table: "Role",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "CreationUserId",
table: "Role",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AddPrimaryKey(
name: "PK_Role",
table: "Role",
column: "Id");
migrationBuilder.CreateIndex(
name: "IX_Username",
table: "Users",
column: "Username");
migrationBuilder.AddForeignKey(
name: "FK_Users_Role_RoleId",
table: "Users",
column: "RoleId",
principalTable: "Role",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@@ -0,0 +1,167 @@
// <auto-generated />
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("20250316212343_AlterBaseUpdateTimeDeletionTimeNullable")]
partial class AlterBaseUpdateTimeDeletionTimeNullable
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsTestUser")
.HasColumnType("bit");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordSalt")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RoleId")
.HasColumnType("int");
b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Role");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MainProject.Migrations
{
/// <inheritdoc />
public partial class AlterBaseUpdateTimeDeletionTimeNullable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "UpdateTime",
table: "Users",
type: "datetime2",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "DeletionTime",
table: "Users",
type: "datetime2",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "UpdateTime",
table: "Roles",
type: "datetime2",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "DeletionTime",
table: "Roles",
type: "datetime2",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "UpdateTime",
table: "Users",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
migrationBuilder.AlterColumn<DateTime>(
name: "DeletionTime",
table: "Users",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
migrationBuilder.AlterColumn<DateTime>(
name: "UpdateTime",
table: "Roles",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
migrationBuilder.AlterColumn<DateTime>(
name: "DeletionTime",
table: "Roles",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
}
}
}

View File

@@ -0,0 +1,170 @@
// <auto-generated />
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("20250316212722_AlterTableRoleAddedIsNotEditable")]
partial class AlterTableRoleAddedIsNotEditable
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsNotEditable")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<int?>("CreationUserId")
.HasColumnType("int");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2");
b.Property<int?>("DeletionUserId")
.HasColumnType("int");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Guid")
.IsRequired()
.HasMaxLength(45)
.HasColumnType("nvarchar(45)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsTestUser")
.HasColumnType("bit");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordSalt")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RoleId")
.HasColumnType("int");
b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2");
b.Property<int?>("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.User", b =>
{
b.HasOne("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.Role", "Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Role");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MainProject.Migrations
{
/// <inheritdoc />
public partial class AlterTableRoleAddedIsNotEditable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsNotEditable",
table: "Roles",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsNotEditable",
table: "Roles");
}
}
}

View File

@@ -33,13 +33,13 @@ namespace MainProject.Migrations
b.Property<DateTime>("CreationTime") b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("CreationUserId") b.Property<int?>("CreationUserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<DateTime>("DeletionTime") b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("DeletionUserId") b.Property<int?>("DeletionUserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("Guid") b.Property<string>("Guid")
@@ -50,19 +50,26 @@ namespace MainProject.Migrations
b.Property<bool>("IsDeleted") b.Property<bool>("IsDeleted")
.HasColumnType("bit"); .HasColumnType("bit");
b.Property<bool>("IsNotEditable")
.HasColumnType("bit");
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<DateTime>("UpdateTime") b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("UpdateUserId") b.Property<int?>("UpdateUserId")
.HasColumnType("int"); .HasColumnType("int");
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Role"); b.HasIndex(new[] { "IsDeleted", "Guid" }, "IX_IsDeleted_Guid")
.HasFilter("[IsDeleted] = 0");
b.ToTable("Roles");
}); });
modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.User", b => modelBuilder.Entity("BasicDotnetTemplate.MainProject.Models.Database.SqlServer.User", b =>
@@ -76,13 +83,13 @@ namespace MainProject.Migrations
b.Property<DateTime>("CreationTime") b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("CreationUserId") b.Property<int?>("CreationUserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<DateTime>("DeletionTime") b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("DeletionUserId") b.Property<int?>("DeletionUserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("Email") b.Property<string>("Email")
@@ -126,17 +133,12 @@ namespace MainProject.Migrations
b.Property<int>("RoleId") b.Property<int>("RoleId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<DateTime>("UpdateTime") b.Property<DateTime?>("UpdateTime")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int>("UpdateUserId") b.Property<int?>("UpdateUserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("Username")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("RoleId"); b.HasIndex("RoleId");
@@ -146,8 +148,6 @@ namespace MainProject.Migrations
b.HasIndex(new[] { "IsDeleted", "Guid" }, "IX_IsDeleted_Guid") b.HasIndex(new[] { "IsDeleted", "Guid" }, "IX_IsDeleted_Guid")
.HasFilter("[IsDeleted] = 0"); .HasFilter("[IsDeleted] = 0");
b.HasIndex(new[] { "Username" }, "IX_Username");
b.ToTable("Users"); b.ToTable("Users");
}); });

View File

@@ -7,7 +7,6 @@ public class AuthenticatedUser
{ {
#nullable enable #nullable enable
public string? Guid { get; set; } public string? Guid { get; set; }
public string? Username { get; set; }
public string? FirstName { get; set; } public string? FirstName { get; set; }
public string? LastName { get; set; } public string? LastName { get; set; }
public string? Email { get; set; } public string? Email { get; set; }
@@ -17,7 +16,6 @@ public class AuthenticatedUser
public AuthenticatedUser(DatabaseSqlServer.User user) public AuthenticatedUser(DatabaseSqlServer.User user)
{ {
Guid = user.Guid; Guid = user.Guid;
Username = user.Username;
FirstName = user.FirstName; FirstName = user.FirstName;
LastName = user.LastName; LastName = user.LastName;
Email = user.Email; Email = user.Email;

View File

@@ -7,7 +7,6 @@ public class UserDto
{ {
#nullable enable #nullable enable
public string? Guid { get; set; } public string? Guid { get; set; }
public string? Username { get; set; }
public string? FirstName { get; set; } public string? FirstName { get; set; }
public string? LastName { get; set; } public string? LastName { get; set; }
public string? Email { get; set; } public string? Email { get; set; }

View File

@@ -3,7 +3,7 @@ namespace BasicDotnetTemplate.MainProject.Models.Api.Data.Auth;
public class AuthenticateRequestData public class AuthenticateRequestData
{ {
#nullable enable #nullable enable
public string? Username { get; set; } public string? Email { get; set; }
public string? Password { get; set; } public string? Password { get; set; }
#nullable disable #nullable disable
} }

View File

@@ -0,0 +1,8 @@
namespace BasicDotnetTemplate.MainProject.Models.Api.Data.Role;
public class CreateRoleRequestData
{
public string Name { get; set; } = String.Empty;
public required bool IsNotEditable { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace BasicDotnetTemplate.MainProject.Models.Api.Data.User;
public class CreateUserRequestData
{
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; }
}

View File

@@ -0,0 +1,14 @@
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
}

View File

@@ -10,11 +10,13 @@ public class Base
public string Guid { get; set; } public string Guid { get; set; }
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public DateTime CreationTime { get; set; } public DateTime CreationTime { get; set; }
public int CreationUserId { get; set; } #nullable enable
public DateTime UpdateTime { get; set; } public int? CreationUserId { get; set; }
public int UpdateUserId { get; set; } public DateTime? UpdateTime { get; set; }
public DateTime DeletionTime { get; set; } public int? UpdateUserId { get; set; }
public int DeletionUserId { get; set; } public DateTime? DeletionTime { get; set; }
public int? DeletionUserId { get; set; }
#nullable disable
} }

View File

@@ -1,10 +1,12 @@
using System.Text.Json.Serialization; using System.ComponentModel.DataAnnotations;
namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer
{ {
public class Role : Base public class Role : Base
{ {
[MaxLength(100)]
public required string Name { get; set; } public required string Name { get; set; }
public required bool IsNotEditable { get; set; }
} }
} }

View File

@@ -6,8 +6,6 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
public class User : Base public class User : Base
{ {
[MaxLength(200)]
public required string Username { get; set; }
[MaxLength(200)] [MaxLength(200)]
public required string FirstName { get; set; } public required string FirstName { get; set; }
[MaxLength(200)] [MaxLength(200)]

View File

@@ -44,6 +44,7 @@ internal static class Program
ProgramUtils.AddDbContext(ref builder, appSettings); ProgramUtils.AddDbContext(ref builder, appSettings);
WebApplication app = builder.Build(); WebApplication app = builder.Build();
ProgramUtils.AddMiddlewares(ref app); ProgramUtils.AddMiddlewares(ref app);
ProgramUtils.CreateRoles(ref app);
Logger.Info("[Program][Initialize] End building"); Logger.Info("[Program][Initialize] End building");
return app; return app;

View File

@@ -17,10 +17,11 @@ public class AuthService : BaseService, IAuthService
protected readonly IUserService _userService; protected readonly IUserService _userService;
public AuthService( public AuthService(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration, IConfiguration configuration,
SqlServerContext sqlServerContext, SqlServerContext sqlServerContext,
IUserService userService IUserService userService
) : base(configuration, sqlServerContext) ) : base(httpContextAccessor, configuration, sqlServerContext)
{ {
_cryptUtils = new CryptUtils(_appSettings); _cryptUtils = new CryptUtils(_appSettings);
_userService = userService; _userService = userService;
@@ -29,7 +30,8 @@ public class AuthService : BaseService, IAuthService
public async Task<AuthenticatedUser?> AuthenticateAsync(AuthenticateRequestData data) public async Task<AuthenticatedUser?> AuthenticateAsync(AuthenticateRequestData data)
{ {
AuthenticatedUser? authenticatedUser = null; AuthenticatedUser? authenticatedUser = null;
var decryptedUsername = _cryptUtils.Decrypt(data.Username ?? String.Empty);
var decryptedUsername = _cryptUtils.Decrypt(data.Email ?? String.Empty);
var decryptedPassword = _cryptUtils.Decrypt(data.Password ?? String.Empty); var decryptedPassword = _cryptUtils.Decrypt(data.Password ?? String.Empty);
if (!String.IsNullOrEmpty(decryptedUsername) && !String.IsNullOrEmpty(decryptedPassword)) if (!String.IsNullOrEmpty(decryptedUsername) && !String.IsNullOrEmpty(decryptedPassword))

View File

@@ -1,23 +1,43 @@
using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Models.Api.Common.User;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
namespace BasicDotnetTemplate.MainProject.Services; namespace BasicDotnetTemplate.MainProject.Services;
public class BaseService public class BaseService
{ {
private readonly IHttpContextAccessor _httpContextAccessor;
protected readonly IConfiguration _configuration; protected readonly IConfiguration _configuration;
protected readonly AppSettings _appSettings; protected readonly AppSettings _appSettings;
protected readonly SqlServerContext _sqlServerContext; protected readonly SqlServerContext _sqlServerContext;
public BaseService( public BaseService(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration, IConfiguration configuration,
SqlServerContext sqlServerContext SqlServerContext sqlServerContext
) )
{ {
_httpContextAccessor = httpContextAccessor;
_configuration = configuration; _configuration = configuration;
_appSettings = new AppSettings(); _appSettings = new AppSettings();
_configuration.GetSection("AppSettings").Bind(_appSettings); _configuration.GetSection("AppSettings").Bind(_appSettings);
_sqlServerContext = sqlServerContext; _sqlServerContext = sqlServerContext;
} }
protected int? GetCurrentUserId()
{
int? userId = null;
var user = this.GetCurrentUser();
if (user != null)
{
userId = this._sqlServerContext.Users.Where(x => !x.IsDeleted && x.Guid == user.Guid).FirstOrDefault()?.Id;
}
return userId;
}
protected AuthenticatedUser? GetCurrentUser()
{
return _httpContextAccessor.HttpContext?.Items["User"] as AuthenticatedUser;
}
} }

View File

@@ -21,10 +21,10 @@ public class JwtService : BaseService, IJwtService
private readonly JwtTokenUtils _jwtTokenUtils; private readonly JwtTokenUtils _jwtTokenUtils;
public JwtService( public JwtService(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration, IConfiguration configuration,
SqlServerContext sqlServerContext, SqlServerContext sqlServerContext
IUserService userService ) : base(httpContextAccessor, configuration, sqlServerContext)
) : base(configuration, sqlServerContext)
{ {
_jwtTokenUtils = new JwtTokenUtils(_appSettings); _jwtTokenUtils = new JwtTokenUtils(_appSettings);
} }

View File

@@ -0,0 +1,103 @@
using System.Collections;
using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Models.Api.Data.Role;
using BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
using Microsoft.EntityFrameworkCore;
namespace BasicDotnetTemplate.MainProject.Services;
public interface IRoleService
{
Task<Role?> GetRoleByIdAsync(int id);
Task<Role?> GetRoleByGuidAsync(string guid);
Task<bool> CheckIfNameIsValid(string name, string? guid = "");
Task<Role?> CreateRole(CreateRoleRequestData data);
}
public class RoleService : BaseService, IRoleService
{
public RoleService(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration,
SqlServerContext sqlServerContext
) : base(httpContextAccessor, configuration, sqlServerContext)
{ }
private IQueryable<Role> GetRolesQueryable()
{
return this._sqlServerContext.Roles.Where(x => !x.IsDeleted);
}
private IQueryable<Role> GetRoleByNameQueryable(string name)
{
return this.GetRolesQueryable().Where(x =>
x.Name.ToString() == name.ToString()
);
}
private Role CreateRoleData(CreateRoleRequestData data)
{
Role role = new()
{
CreationTime = DateTime.UtcNow,
CreationUserId = this.GetCurrentUserId(),
IsDeleted = false,
Guid = Guid.NewGuid().ToString(),
Name = data.Name,
IsNotEditable = data.IsNotEditable
};
return role;
}
public async Task<Role?> GetRoleByIdAsync(int id)
{
return await this.GetRolesQueryable().Where(x => x.Id == id).FirstOrDefaultAsync();
}
public async Task<Role?> GetRoleByGuidAsync(string guid)
{
return await this.GetRolesQueryable().Where(x => x.Guid == guid).FirstOrDefaultAsync();
}
public async Task<bool> CheckIfNameIsValid(string name, string? guid = "")
{
var valid = false;
Role? role = await this.GetRoleByNameQueryable(name).FirstOrDefaultAsync();
if (role != null)
{
if (!String.IsNullOrEmpty(guid))
{
valid = role.Guid == guid && role.Name == name;
}
}
else
{
valid = true;
}
return valid;
}
public async Task<Role?> CreateRole(CreateRoleRequestData data)
{
Role? role = null;
using (var transaction = _sqlServerContext.Database.BeginTransactionAsync())
{
var tempRole = this.CreateRoleData(data);
await _sqlServerContext.Roles.AddAsync(tempRole);
await _sqlServerContext.SaveChangesAsync();
await (await transaction).CommitAsync();
role = tempRole;
}
return role;
}
}

View File

@@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Models.Api.Data.User;
using BasicDotnetTemplate.MainProject.Models.Database.SqlServer; using BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -10,65 +11,109 @@ public interface IUserService
{ {
Task<User?> GetUserByIdAsync(int id); Task<User?> GetUserByIdAsync(int id);
Task<User?> GetUserByGuidAsync(string guid); Task<User?> GetUserByGuidAsync(string guid);
Task<User?> GetUserByUsernameAndPassword(string username, string password); Task<User?> GetUserByUsernameAndPassword(string email, string password);
Task<bool> CheckIfEmailIsValid(string email, string? guid = "");
Task<User?> CreateUser(CreateUserRequestData data, Role role);
} }
public class UserService : BaseService, IUserService public class UserService : BaseService, IUserService
{ {
public UserService( public UserService(
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration, IConfiguration configuration,
SqlServerContext sqlServerContext SqlServerContext sqlServerContext
) : base(configuration, sqlServerContext) ) : base(httpContextAccessor, configuration, sqlServerContext)
{ } { }
private IQueryable<User> GetUsers() private IQueryable<User> GetUsersQueryable()
{ {
return this._sqlServerContext.Users.Where(x => !x.IsDeleted); return this._sqlServerContext.Users.Where(x => !x.IsDeleted);
} }
private IQueryable<User> GetUserByUsername(string username) private IQueryable<User> GetUserByEmailQueryable(string email)
{ {
return this.GetUsers().Where(x => return this.GetUsersQueryable().Where(x =>
x.Username.ToString() == username.ToString() x.Email.ToString() == email.ToString()
); );
} }
private User CreateUserData(CreateUserRequestData data, Role role)
{
User user = new()
{
CreationTime = DateTime.UtcNow,
CreationUserId = this.GetCurrentUserId(),
IsDeleted = false,
Guid = Guid.NewGuid().ToString(),
FirstName = data.FirstName,
LastName = data.LastName,
Email = data.Email,
PasswordSalt = "",
PasswordHash = "",
Password = "",
Role = role,
IsTestUser = false
};
return user;
}
public async Task<User?> GetUserByIdAsync(int id) public async Task<User?> GetUserByIdAsync(int id)
{ {
return await this.GetUsers().Where(x => x.Id == id).FirstOrDefaultAsync(); return await this.GetUsersQueryable().Where(x => x.Id == id).FirstOrDefaultAsync();
} }
public async Task<User?> GetUserByGuidAsync(string guid) public async Task<User?> GetUserByGuidAsync(string guid)
{ {
return await this.GetUsers().Where(x => x.Guid == guid).FirstOrDefaultAsync(); return await this.GetUsersQueryable().Where(x => x.Guid == guid).FirstOrDefaultAsync();
} }
public async Task<User?> GetUserByUsernameAndPassword(string username, string password) public async Task<User?> GetUserByUsernameAndPassword(string email, string password)
{ {
User? user = null; User? user = await this.GetUserByEmailQueryable(email).FirstOrDefaultAsync();
try
{
user = await this.GetUserByUsername(username).FirstOrDefaultAsync();
if (user != null) if (user != null)
{ {
var encryptedPassword = user.PasswordHash; var encryptedPassword = user.PasswordHash;
Console.WriteLine(encryptedPassword); Console.WriteLine(encryptedPassword);
} }
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
return user; return user;
} }
// public async Task<User?> CreateUser(CreateUserRequestData data) public async Task<bool> CheckIfEmailIsValid(string email, string? guid = "")
// { {
var valid = false;
// } User? user = await this.GetUserByEmailQueryable(email).FirstOrDefaultAsync();
if (user != null)
{
if (!String.IsNullOrEmpty(guid))
{
valid = user.Guid == guid && user.Email == email;
}
}
else
{
valid = true;
}
return valid;
}
public async Task<User?> CreateUser(CreateUserRequestData data, Role role)
{
User? user = null;
using (var transaction = _sqlServerContext.Database.BeginTransactionAsync())
{
var tempUser = this.CreateUserData(data, role);
}
return user;
}
} }

View File

@@ -6,6 +6,8 @@ using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Core.Middlewares; using BasicDotnetTemplate.MainProject.Core.Middlewares;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using BasicDotnetTemplate.MainProject.Services; using BasicDotnetTemplate.MainProject.Services;
using BasicDotnetTemplate.MainProject.Models.Api.Data.Role;
using BasicDotnetTemplate.MainProject.Models.Database.SqlServer;
@@ -213,8 +215,10 @@ public static class ProgramUtils
public static void AddScopes(ref WebApplicationBuilder builder) public static void AddScopes(ref WebApplicationBuilder builder)
{ {
Logger.Info("[ProgramUtils][AddScopes] Adding scopes"); Logger.Info("[ProgramUtils][AddScopes] Adding scopes");
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<IAuthService, AuthService>(); builder.Services.AddScoped<IAuthService, AuthService>();
builder.Services.AddScoped<IJwtService, JwtService>(); builder.Services.AddScoped<IJwtService, JwtService>();
builder.Services.AddScoped<IRoleService, RoleService>();
builder.Services.AddScoped<IUserService, UserService>(); builder.Services.AddScoped<IUserService, UserService>();
Logger.Info("[ProgramUtils][AddScopes] Done scopes"); Logger.Info("[ProgramUtils][AddScopes] Done scopes");
} }
@@ -226,4 +230,45 @@ public static class ProgramUtils
Logger.Info("[ProgramUtils][AddScopes] Done AutoMapperConfiguration"); Logger.Info("[ProgramUtils][AddScopes] Done AutoMapperConfiguration");
} }
public static void CreateRoles(ref WebApplication app)
{
Logger.Info("[ProgramUtils][CreateRoles] Adding roles...");
using (var scope = app.Services.CreateScope())
{
var roleService = scope.ServiceProvider.GetRequiredService<IRoleService>;
CreateRole(roleService, "Administrator");
CreateRole(roleService, "Default");
}
Logger.Info("[ProgramUtils][CreateRoles] Done roles");
}
private static void CreateRole(Func<IRoleService?> roleService, string roleName)
{
Logger.Info($"[ProgramUtils][CreateRole] Adding role {roleName}...");
if (roleService != null)
{
var isValidThread = Task.Run(() => roleService!.Invoke()?.CheckIfNameIsValid(roleName));
if (isValidThread.Result)
{
CreateRoleRequestData data = new()
{
Name = roleName,
IsNotEditable = true
};
var createThread = Task.Run(() => roleService!.Invoke()?.CreateRole(data));
Role? role = createThread.Result;
if (role != null)
{
Logger.Info($"[ProgramUtils][CreateRole] Role {roleName} created...");
}
}
else
{
Logger.Info($"[ProgramUtils][CreateRole] Role {roleName} already exists...");
}
}
}
} }