Trying to integrate 2FA and messing it up
This commit is contained in:
parent
31dde9f33c
commit
8f54854822
@ -1,4 +1,4 @@
|
|||||||
namespace Project.Application.DTOs.Auth
|
namespace Project.Application.DTOs.Auth
|
||||||
{
|
{
|
||||||
public record LoginDto(string Username, string Password);
|
public record LoginDto(string Email, string Password);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
{
|
{
|
||||||
public class CreatingUserDto
|
public class CreatingUserDto
|
||||||
{
|
{
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
public string FirstName { get; set; }
|
public string FirstName { get; set; }
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
public string FirstName { get; set; }
|
public string FirstName { get; set; }
|
||||||
|
|||||||
@ -4,11 +4,14 @@
|
|||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
public string UserName { 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 ReadingRoleDto? Role { get; set; }
|
public ReadingRoleDto? Role { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
namespace Project.Application.DTOs.TwoFactorAuth
|
||||||
|
{
|
||||||
|
public class TwoFactorSetupDto
|
||||||
|
{
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
public string QrCodeImageUrl { get; set; }
|
||||||
|
public string ManualEntryKey { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace Project.Application.DTOs.TwoFactorAuth
|
||||||
|
{
|
||||||
|
public class TwoFactorVerificationDto
|
||||||
|
{
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Code { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Project.Application/Interfaces/ITwoFactorAuthService.cs
Normal file
19
Project.Application/Interfaces/ITwoFactorAuthService.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Project.Application.DTOs.TwoFactorAuth;
|
||||||
|
|
||||||
|
namespace Project.Application.Interfaces
|
||||||
|
{
|
||||||
|
public interface ITwoFactorAuthService
|
||||||
|
{
|
||||||
|
// GENERATE TWO FACTOR AUTH SETUP
|
||||||
|
public Task<TwoFactorSetupDto> GenerateSetupCodeAsync(string userEmail);
|
||||||
|
|
||||||
|
// VALIDATE OTP
|
||||||
|
public Task<bool> ValidateCodeAsync(string userEmail, string code);
|
||||||
|
|
||||||
|
//// SAVE SECRET KEY
|
||||||
|
//public Task SaveSecretKeyAsync(string userEmail, string userSecretKey);
|
||||||
|
|
||||||
|
// GET SECRET KEY
|
||||||
|
public Task<string> GetSecretKeyAsync(string userEmail);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,8 +15,8 @@ namespace Project.Application.Interfaces
|
|||||||
// READ BY ID
|
// READ BY ID
|
||||||
Task<ReadingUserDto> GetByIdAsync(int id);
|
Task<ReadingUserDto> GetByIdAsync(int id);
|
||||||
|
|
||||||
// READ BY USERNAME
|
// READ BY EMAIL
|
||||||
Task<ReadingUserDto> GetByUsernameAsync(string username);
|
Task<ReadingUserDto> GetByEmailAsync(string email);
|
||||||
|
|
||||||
// UPDATE
|
// UPDATE
|
||||||
Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto);
|
Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Project.Application.DTOs.Incoming;
|
using Project.Application.DTOs.Incoming;
|
||||||
using Project.Application.DTOs.Outgoing;
|
using Project.Application.DTOs.Outgoing;
|
||||||
|
using Project.Application.DTOs.TwoFactorAuth;
|
||||||
using Project.Domain.Entities;
|
using Project.Domain.Entities;
|
||||||
|
|
||||||
namespace Project.Application.MappingProfiles
|
namespace Project.Application.MappingProfiles
|
||||||
|
|||||||
9
Project.Application/Options/AuthOptions.cs
Normal file
9
Project.Application/Options/AuthOptions.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Project.Application.Options
|
||||||
|
{
|
||||||
|
public class AuthOptions
|
||||||
|
{
|
||||||
|
public required string ApiKey { get; init; }
|
||||||
|
public required string Issuer { get; init; }
|
||||||
|
public required string SecretKey { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="GoogleAuthenticator" Version="3.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Project.Application.Interfaces;
|
using Project.Application.Interfaces;
|
||||||
using Project.Domain.Entities;
|
|
||||||
using Project.Infrastructure.Interfaces;
|
using Project.Infrastructure.Interfaces;
|
||||||
|
|
||||||
namespace Project.Application.Services
|
namespace Project.Application.Services
|
||||||
@ -8,19 +7,45 @@ namespace Project.Application.Services
|
|||||||
{
|
{
|
||||||
// FIELDS FOR CTOR
|
// FIELDS FOR CTOR
|
||||||
private IUserRepository _userRepository;
|
private IUserRepository _userRepository;
|
||||||
|
private readonly ITwoFactorAuthService _twoFactorAuthService;
|
||||||
|
|
||||||
// CTOR
|
// CTOR
|
||||||
public AuthService(IUserRepository userRepository)
|
public AuthService(IUserRepository userRepository, ITwoFactorAuthService twoFactorAuthService)
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
|
_twoFactorAuthService = twoFactorAuthService;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTHENTICATE
|
// AUTHENTICATE
|
||||||
public async Task<bool> ValidateAsync(string username, string password)
|
public async Task<bool> ValidateAsync(string email, string password)
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByUsernameAsync(username);
|
var user = await _userRepository.GetByEmailAsync(email);
|
||||||
|
|
||||||
return user?.Password == password;
|
if (user == null || user.Password != password)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if 2FA is enabled
|
||||||
|
if (!string.IsNullOrEmpty(user.SecretKey))
|
||||||
|
{
|
||||||
|
return false; // 2FA is enabled and additional validation is required
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VALIDATE TWO FACTOR AUTHENTICATION
|
||||||
|
public async Task<bool> ValidateTwoFactorAsync(string email, string code)
|
||||||
|
{
|
||||||
|
var user = await _userRepository.GetByEmailAsync(email);
|
||||||
|
|
||||||
|
if (user == null || string.IsNullOrEmpty(user.SecretKey))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _twoFactorAuthService.ValidateCodeAsync(user.Email, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
97
Project.Application/Services/TwoFactorAuthService.cs
Normal file
97
Project.Application/Services/TwoFactorAuthService.cs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
using Google.Authenticator;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Project.Application.DTOs.TwoFactorAuth;
|
||||||
|
using Project.Application.Interfaces;
|
||||||
|
using Project.Application.Options;
|
||||||
|
using Project.Infrastructure.Interfaces;
|
||||||
|
|
||||||
|
namespace Project.Application.Services
|
||||||
|
{
|
||||||
|
public class TwoFactorAuthService : ITwoFactorAuthService
|
||||||
|
{
|
||||||
|
// FIELDS FOR CTOR
|
||||||
|
private readonly TwoFactorAuthenticator _twoFactorAuthenticator;
|
||||||
|
private readonly ITwoFactorAuthRepository _twoFactorAuthRepository;
|
||||||
|
private readonly string _issuer;
|
||||||
|
|
||||||
|
// CTOR
|
||||||
|
public TwoFactorAuthService(IOptions<AuthOptions> options, ITwoFactorAuthRepository twoFactorAuthRepository)
|
||||||
|
{
|
||||||
|
_twoFactorAuthenticator = new TwoFactorAuthenticator();
|
||||||
|
_twoFactorAuthRepository = twoFactorAuthRepository;
|
||||||
|
_issuer = options.Value.Issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public void TwoFactorAuthenticatorMethods()
|
||||||
|
//{
|
||||||
|
// _twoFactorAuthenticator.Equals();
|
||||||
|
// _twoFactorAuthenticator.GeneratePINAtInterval();
|
||||||
|
// _twoFactorAuthenticator.GenerateSetupCode();
|
||||||
|
// _twoFactorAuthenticator.GetCurrentPIN();
|
||||||
|
// _twoFactorAuthenticator.GetCurrentPINs();
|
||||||
|
// _twoFactorAuthenticator.GetHashCode();
|
||||||
|
// _twoFactorAuthenticator.GetType();
|
||||||
|
// _twoFactorAuthenticator.ToString();
|
||||||
|
// _twoFactorAuthenticator.ValidateTwoFactorPIN();
|
||||||
|
//}
|
||||||
|
|
||||||
|
// GENERATE TWO FACTOR AUTH SETUP
|
||||||
|
public async Task<TwoFactorSetupDto> GenerateSetupCodeAsync(string userEmail)
|
||||||
|
{
|
||||||
|
var userSecretKey = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
var setupInfo = _twoFactorAuthenticator.GenerateSetupCode(
|
||||||
|
_issuer, // Envelope.Configuration.ApplicationName
|
||||||
|
userEmail, // user.Email
|
||||||
|
userSecretKey,
|
||||||
|
false,
|
||||||
|
10);
|
||||||
|
|
||||||
|
string manualEntryKey = setupInfo.ManualEntryKey;
|
||||||
|
string qrCodeImageUrl = setupInfo.QrCodeSetupImageUrl;
|
||||||
|
|
||||||
|
await _twoFactorAuthRepository.SaveSecretKeyAsync(userEmail, userSecretKey);
|
||||||
|
|
||||||
|
return new TwoFactorSetupDto
|
||||||
|
{
|
||||||
|
SecretKey = userSecretKey,
|
||||||
|
QrCodeImageUrl = qrCodeImageUrl,
|
||||||
|
ManualEntryKey = manualEntryKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// VALIDATE OTP
|
||||||
|
public async Task<bool> ValidateCodeAsync(string userEmail, string userInputCode)
|
||||||
|
{
|
||||||
|
var secretKey = await _twoFactorAuthRepository.GetSecretKeyAsync(userEmail);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(secretKey))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Secret key not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _twoFactorAuthenticator.ValidateTwoFactorPIN(secretKey, userInputCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// SAVE SECRET KEY
|
||||||
|
//public async Task SaveSecretKeyAsync(string userEmail, string userSecretKey)
|
||||||
|
//{
|
||||||
|
// var user = await _twoFactorAuthRepository.GetUserByEmailAsync(userEmail);
|
||||||
|
|
||||||
|
// if (user == null)
|
||||||
|
// {
|
||||||
|
// throw new InvalidOperationException("User not found!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await _twoFactorAuthRepository.SaveSecretKeyAsync(userEmail, userSecretKey);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// GET SECRET KEY
|
||||||
|
public async Task<string> GetSecretKeyAsync(string userEmail)
|
||||||
|
{
|
||||||
|
var secretKey = await _twoFactorAuthRepository.GetSecretKeyAsync(userEmail);
|
||||||
|
|
||||||
|
return secretKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -54,10 +54,10 @@ namespace Project.Application.Services
|
|||||||
return readDto;
|
return readDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// READ BY USERNAME
|
// READ BY EMAIL
|
||||||
public async Task<ReadingUserDto> GetByUsernameAsync(string username)
|
public async Task<ReadingUserDto> GetByEmailAsync(string email)
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByUsernameAsync(username);
|
var user = await _userRepository.GetByEmailAsync(email);
|
||||||
var readDto = _mapper.Map<ReadingUserDto>(user);
|
var readDto = _mapper.Map<ReadingUserDto>(user);
|
||||||
return readDto;
|
return readDto;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,15 @@ namespace Project.Domain.Entities
|
|||||||
[Table("USER", Schema = "dbo")]
|
[Table("USER", Schema = "dbo")]
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
[Column("ID")]
|
|
||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
[Column("ID")]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("EMAIL")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("USER_NAME")]
|
[Column("USER_NAME")]
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
@ -27,9 +31,13 @@ namespace Project.Domain.Entities
|
|||||||
[Column("PASSWORD")]
|
[Column("PASSWORD")]
|
||||||
public string Password { get; init; }
|
public string Password { get; init; }
|
||||||
|
|
||||||
|
[Column("ROLE_ID")]
|
||||||
public int RoleId { get; set; }
|
public int RoleId { get; set; }
|
||||||
|
|
||||||
[ForeignKey("RoleId")]
|
[ForeignKey("ROLE")]
|
||||||
public Role? Role { get; set; }
|
public Role? Role { get; set; }
|
||||||
|
|
||||||
|
[Column("SECRET_KEY")]
|
||||||
|
public string SecretKey { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="GoogleAuthenticator" Version="3.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
using Project.Domain.Entities;
|
||||||
|
|
||||||
|
namespace Project.Infrastructure.Interfaces
|
||||||
|
{
|
||||||
|
public interface ITwoFactorAuthRepository
|
||||||
|
{
|
||||||
|
// GET USER BY EMAIL
|
||||||
|
Task<User> GetUserByEmailAsync(string email);
|
||||||
|
|
||||||
|
// GET SECRET KEY
|
||||||
|
Task<string> GetSecretKeyAsync(string email);
|
||||||
|
|
||||||
|
// SAVE SECRET KEY
|
||||||
|
Task<bool> SaveSecretKeyAsync(string email, string secretKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,8 +13,8 @@ namespace Project.Infrastructure.Interfaces
|
|||||||
// READ BY ID
|
// READ BY ID
|
||||||
Task<User?> GetByIdAsync(int id);
|
Task<User?> GetByIdAsync(int id);
|
||||||
|
|
||||||
// READ BY USERNAME
|
// READ BY EMAIL
|
||||||
Task<User?> GetByUsernameAsync(string username);
|
Task<User?> GetByEmailAsync(string email);
|
||||||
|
|
||||||
// UPDATE
|
// UPDATE
|
||||||
Task<bool> UpdateAsync(User user);
|
Task<bool> UpdateAsync(User user);
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
|
<PackageReference Include="GoogleAuthenticator" Version="3.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Project.Domain.Entities;
|
||||||
|
using Project.Infrastructure.Interfaces;
|
||||||
|
|
||||||
|
namespace Project.Infrastructure.Repositories
|
||||||
|
{
|
||||||
|
public class TwoFactorAuthRepository : ITwoFactorAuthRepository
|
||||||
|
{
|
||||||
|
// FIELDS FOR CTOR
|
||||||
|
private readonly ApplicationDbContext _context;
|
||||||
|
|
||||||
|
// CTOR
|
||||||
|
public TwoFactorAuthRepository(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET USER BY EMAIL
|
||||||
|
public async Task<User> GetUserByEmailAsync(string email)
|
||||||
|
{
|
||||||
|
return await _context.Users.FirstAsync(user => user.Email == email);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET SECRET KEY
|
||||||
|
public async Task<string> GetSecretKeyAsync(string email)
|
||||||
|
{
|
||||||
|
return await _context.Users
|
||||||
|
.Where(user => user.Email == email)
|
||||||
|
.Select(user => user.SecretKey)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAVE SECRET KEY
|
||||||
|
public async Task<bool> SaveSecretKeyAsync(string email, string secretKey)
|
||||||
|
{
|
||||||
|
User user = await _context.Users.FirstAsync(user => user.Email == email);
|
||||||
|
|
||||||
|
user.SecretKey = secretKey;
|
||||||
|
|
||||||
|
_context.Entry(user).State = EntityState.Modified;
|
||||||
|
var results = await _context.SaveChangesAsync();
|
||||||
|
return results > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -35,10 +35,10 @@ namespace Project.Infrastructure.Repositories
|
|||||||
return await _context.Users.Where(user => user.Id == id).Include(user => user.Role).FirstAsync(); // Role important for authorization
|
return await _context.Users.Where(user => user.Id == id).Include(user => user.Role).FirstAsync(); // Role important for authorization
|
||||||
}
|
}
|
||||||
|
|
||||||
// READ BY USERNAME
|
// READ BY EMAIL
|
||||||
public async Task<User?> GetByUsernameAsync(string username)
|
public async Task<User?> GetByEmailAsync(string email)
|
||||||
{
|
{
|
||||||
return await _context.Users.Include(user => user.Role).FirstOrDefaultAsync(u => u.UserName == username); // Role important for authorization
|
return await _context.Users.Include(user => user.Role).FirstOrDefaultAsync(u => u.Email == email); // Role important for authorization
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATE
|
// UPDATE
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authentication.Cookies;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Project.Application.DTOs.Auth;
|
using Project.Application.DTOs.Auth;
|
||||||
|
using Project.Application.DTOs.TwoFactorAuth;
|
||||||
using Project.Application.Interfaces;
|
using Project.Application.Interfaces;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
@ -15,38 +16,49 @@ namespace Project.Web.Controllers
|
|||||||
// FIELDS FOR CTOR
|
// FIELDS FOR CTOR
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IAuthService _authService;
|
private readonly IAuthService _authService;
|
||||||
|
private readonly ITwoFactorAuthService _twoFactorAuthService;
|
||||||
|
|
||||||
// CTOR
|
// CTOR
|
||||||
public AuthController(IUserService userService, IAuthService authService)
|
public AuthController(IUserService userService, IAuthService authService, ITwoFactorAuthService twoFactorAuthService)
|
||||||
{
|
{
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_authService = authService;
|
_authService = authService;
|
||||||
|
_twoFactorAuthService = twoFactorAuthService;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOGIN
|
// LOGIN
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
public async Task<IActionResult> Login([FromBody] LoginDto login)
|
public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
|
||||||
{
|
{
|
||||||
// Validate login credentials
|
// Validate login credentials
|
||||||
var isValid = await _authService.ValidateAsync(login.Username, login.Password);
|
bool isValid = await _authService.ValidateAsync(loginDto.Email, loginDto.Password);
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
{
|
{
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate user
|
// Validate user
|
||||||
var user = await _userService.GetByUsernameAsync(login.Username);
|
var user = await _userService.GetByEmailAsync(loginDto.Email);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
return Unauthorized(user);
|
return Unauthorized(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if 2FA is required
|
||||||
|
var secretKey = await _twoFactorAuthService.GetSecretKeyAsync(loginDto.Email);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(secretKey))
|
||||||
|
{
|
||||||
|
// Promt for 2FA
|
||||||
|
return Ok(new { RequiresTwoFactor = true });
|
||||||
|
}
|
||||||
|
|
||||||
// Create claims based on the user information
|
// Create claims based on the user information
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
new Claim(ClaimTypes.Name, user.UserName),
|
new Claim(ClaimTypes.Name, user.Email),
|
||||||
new Claim(ClaimTypes.Surname, user.LastName ?? ""),
|
new Claim(ClaimTypes.Surname, user.LastName ?? ""),
|
||||||
new Claim(ClaimTypes.GivenName, user.FirstName ?? ""),
|
new Claim(ClaimTypes.GivenName, user.FirstName ?? ""),
|
||||||
new Claim(ClaimTypes.Role, user?.Role?.Name.ToString() ?? "") // role is important for authorization
|
new Claim(ClaimTypes.Role, user?.Role?.Name.ToString() ?? "") // role is important for authorization
|
||||||
@ -73,13 +85,65 @@ namespace Project.Web.Controllers
|
|||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("verify2fa")]
|
||||||
|
public async Task<IActionResult> Verify2Fa([FromBody] TwoFactorVerificationDto verifyDto)
|
||||||
|
{
|
||||||
|
var isValid = await _twoFactorAuthService.ValidateCodeAsync(verifyDto.Email, verifyDto.Code);
|
||||||
|
if (!isValid)
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userService.GetByEmailAsync(verifyDto.Email);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
|
new Claim(ClaimTypes.Email, user.Email),
|
||||||
|
new Claim(ClaimTypes.Surname, user.LastName ?? ""),
|
||||||
|
new Claim(ClaimTypes.GivenName, user.FirstName ?? ""),
|
||||||
|
new Claim(ClaimTypes.Role, user?.Role?.Name ?? "")
|
||||||
|
};
|
||||||
|
|
||||||
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
|
||||||
|
var authProperties = new AuthenticationProperties
|
||||||
|
{
|
||||||
|
IsPersistent = true,
|
||||||
|
AllowRefresh = true,
|
||||||
|
ExpiresUtc = DateTime.UtcNow.AddMinutes(60)
|
||||||
|
};
|
||||||
|
|
||||||
|
await HttpContext.SignInAsync(
|
||||||
|
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||||
|
new ClaimsPrincipal(claimsIdentity),
|
||||||
|
authProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
// LOGOUT
|
// LOGOUT
|
||||||
[HttpPost("logout")]
|
[HttpPost("logout")]
|
||||||
public async Task<IActionResult> Logout()
|
public async Task<IActionResult> Logout()
|
||||||
{
|
{
|
||||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); // Logout is basically deleting cookies
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// SETUP 2FA
|
||||||
|
//[AllowAnonymous]
|
||||||
|
//[HttpPost("setup-2fa")]
|
||||||
|
//public async Task<IActionResult> SetupTwoFactorAuth([FromBody] SetupTwoFactorDto setupDto)
|
||||||
|
//{
|
||||||
|
// var result = await _twoFactorAuthService.GenerateSetupCodeAsync(setupDto.Email);
|
||||||
|
// return Ok(result);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
52
Project.Web/Controllers/TwoFactorAuthController.cs
Normal file
52
Project.Web/Controllers/TwoFactorAuthController.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Project.Application.DTOs.TwoFactorAuth;
|
||||||
|
using Project.Application.Interfaces;
|
||||||
|
|
||||||
|
namespace Project.Web.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class TwoFactorAuthController : ControllerBase
|
||||||
|
{
|
||||||
|
// FEILDS FOR CTOR
|
||||||
|
private readonly ITwoFactorAuthService _twoFactorAuthService;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
|
// CTOR
|
||||||
|
public TwoFactorAuthController(ITwoFactorAuthService twoFactorAuthService, IUserService userService)
|
||||||
|
{
|
||||||
|
_twoFactorAuthService = twoFactorAuthService;
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SETUP 2FA
|
||||||
|
[HttpPost("setup")]
|
||||||
|
public async Task<IActionResult> Setup([FromBody] string email)
|
||||||
|
{
|
||||||
|
var user = await _userService.GetByEmailAsync(email);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var setupInfo = await _twoFactorAuthService.GenerateSetupCodeAsync(email);
|
||||||
|
|
||||||
|
return Ok(setupInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// VERIFY
|
||||||
|
[HttpPost("verify")]
|
||||||
|
public async Task<IActionResult> Verify([FromBody] TwoFactorVerificationDto verifyDto)
|
||||||
|
{
|
||||||
|
var isValid = await _twoFactorAuthService.ValidateCodeAsync(verifyDto.Email, verifyDto.Code);
|
||||||
|
|
||||||
|
if (!isValid)
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@ namespace Project.Web.Controllers
|
|||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize(Roles = "Admin")] // Authorize Admins only to use this controller
|
//[Authorize(Roles = "Admin")] // Authorize Admins only to use this controller
|
||||||
public class UserController : Controller
|
public class UserController : Controller
|
||||||
{
|
{
|
||||||
// FIELDS FOR CTOR
|
// FIELDS FOR CTOR
|
||||||
@ -85,18 +85,18 @@ namespace Project.Web.Controllers
|
|||||||
return Ok(user);
|
return Ok(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
// READ BY USERNAME
|
// READ BY EMAIL
|
||||||
[HttpGet("username/{username}", Name = "GetUserByUsername")]
|
[HttpGet("email/{email}", Name = "GetUserByEmail")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<IActionResult> GetUserByUsername(string username)
|
public async Task<IActionResult> GetUserByEmail(string email)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(username))
|
if (string.IsNullOrEmpty(email))
|
||||||
{
|
{
|
||||||
return BadRequest("Username connot be empty");
|
return BadRequest("Email connot be empty");
|
||||||
}
|
}
|
||||||
var user = await _userService.GetByUsernameAsync(username);
|
var user = await _userService.GetByEmailAsync(email);
|
||||||
if(user == null)
|
if(user == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|||||||
222
Project.Web/Migrations/20240813080158_Zehnte.Designer.cs
generated
Normal file
222
Project.Web/Migrations/20240813080158_Zehnte.Designer.cs
generated
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Project.Infrastructure;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20240813080158_Zehnte")]
|
||||||
|
partial class Zehnte
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("CATEGORY_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY_ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PRODUCT_NAME");
|
||||||
|
|
||||||
|
b.Property<decimal>("Price")
|
||||||
|
.HasColumnType("decimal(18,2)")
|
||||||
|
.HasColumnName("PRICE");
|
||||||
|
|
||||||
|
b.Property<int>("Quantity")
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("QUANTITY");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.ToTable("PRODUCT", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Role", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("ROLE");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("E-MAIL");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("FIRST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("LastName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("LAST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PASSWORD");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("SecretKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("SECRET KEY");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("USER_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("USER", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
Project.Web/Migrations/20240813080158_Zehnte.cs
Normal file
44
Project.Web/Migrations/20240813080158_Zehnte.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Zehnte : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "E-MAIL",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "SECRET KEY",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "E-MAIL",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SECRET KEY",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
225
Project.Web/Migrations/20240813083139_Elfte.Designer.cs
generated
Normal file
225
Project.Web/Migrations/20240813083139_Elfte.Designer.cs
generated
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Project.Infrastructure;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20240813083139_Elfte")]
|
||||||
|
partial class Elfte
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("CATEGORY_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY_ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PRODUCT_NAME");
|
||||||
|
|
||||||
|
b.Property<decimal>("Price")
|
||||||
|
.HasColumnType("decimal(18,2)")
|
||||||
|
.HasColumnName("PRICE");
|
||||||
|
|
||||||
|
b.Property<int>("Quantity")
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("QUANTITY");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.ToTable("PRODUCT", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Role", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("ROLE");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("EMAIL");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("FIRST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("LastName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("LAST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PASSWORD");
|
||||||
|
|
||||||
|
b.Property<int?>("ROLE_ID")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("SecretKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("SECRET_KEY");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("USER_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("USER", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
Project.Web/Migrations/20240813083139_Elfte.cs
Normal file
54
Project.Web/Migrations/20240813083139_Elfte.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Elfte : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "SECRET KEY",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
newName: "SECRET_KEY");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "E-MAIL",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
newName: "EMAIL");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "SECRET_KEY",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
newName: "SECRET KEY");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "EMAIL",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
newName: "E-MAIL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
226
Project.Web/Migrations/20240813083456_Zwoelfte.Designer.cs
generated
Normal file
226
Project.Web/Migrations/20240813083456_Zwoelfte.Designer.cs
generated
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Project.Infrastructure;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20240813083456_Zwoelfte")]
|
||||||
|
partial class Zwoelfte
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("CATEGORY_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("CATEGORY_ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PRODUCT_NAME");
|
||||||
|
|
||||||
|
b.Property<decimal>("Price")
|
||||||
|
.HasColumnType("decimal(18,2)")
|
||||||
|
.HasColumnName("PRICE");
|
||||||
|
|
||||||
|
b.Property<int>("Quantity")
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("QUANTITY");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.ToTable("PRODUCT", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Role", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("CREATION_DATE");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("ROLE");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ROLE", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ID");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("EMAIL");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("FIRST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("LastName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("LAST_NAME");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("PASSWORD");
|
||||||
|
|
||||||
|
b.Property<int?>("ROLE")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ROLE_ID");
|
||||||
|
|
||||||
|
b.Property<string>("SecretKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("SECRET_KEY");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("USER_NAME");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("USER", "dbo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.CategoryRole", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.Product", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Project.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Project.Domain.Entities.Role", "Role")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
Project.Web/Migrations/20240813083456_Zwoelfte.cs
Normal file
115
Project.Web/Migrations/20240813083456_Zwoelfte.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Project.Web.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Zwoelfte : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_USER_ROLE_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_USER_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int",
|
||||||
|
oldNullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "ROLE",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_USER_ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
column: "ROLE_ID");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_USER_ROLE_ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
column: "ROLE_ID",
|
||||||
|
principalSchema: "dbo",
|
||||||
|
principalTable: "ROLE",
|
||||||
|
principalColumn: "ID",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_USER_ROLE_ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_USER_ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ROLE",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "ROLE_ID",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "int",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_USER_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_USER_ROLE_RoleId",
|
||||||
|
schema: "dbo",
|
||||||
|
table: "USER",
|
||||||
|
column: "RoleId",
|
||||||
|
principalSchema: "dbo",
|
||||||
|
principalTable: "ROLE",
|
||||||
|
principalColumn: "ID",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -133,6 +133,11 @@ namespace Project.Web.Migrations
|
|||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("EMAIL");
|
||||||
|
|
||||||
b.Property<string>("FirstName")
|
b.Property<string>("FirstName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)")
|
.HasColumnType("nvarchar(max)")
|
||||||
@ -148,9 +153,18 @@ namespace Project.Web.Migrations
|
|||||||
.HasColumnType("nvarchar(max)")
|
.HasColumnType("nvarchar(max)")
|
||||||
.HasColumnName("PASSWORD");
|
.HasColumnName("PASSWORD");
|
||||||
|
|
||||||
b.Property<int>("RoleId")
|
b.Property<int?>("ROLE")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int")
|
||||||
|
.HasColumnName("ROLE_ID");
|
||||||
|
|
||||||
|
b.Property<string>("SecretKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)")
|
||||||
|
.HasColumnName("SECRET_KEY");
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
b.Property<string>("UserName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)")
|
.HasColumnType("nvarchar(max)")
|
||||||
|
|||||||
@ -12,33 +12,45 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
// Automapper
|
||||||
builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
||||||
|
|
||||||
|
// ProductService, ProductRepository
|
||||||
builder.Services.AddScoped<IProductService, ProductService>();
|
builder.Services.AddScoped<IProductService, ProductService>();
|
||||||
builder.Services.AddScoped<IProductRepository, ProductRepository>();
|
builder.Services.AddScoped<IProductRepository, ProductRepository>();
|
||||||
|
|
||||||
|
// CategoryService, CategoryRepository
|
||||||
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
||||||
builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
|
builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
|
||||||
|
|
||||||
|
// UserService, UserRepository
|
||||||
builder.Services.AddScoped<IUserService, UserService>();
|
builder.Services.AddScoped<IUserService, UserService>();
|
||||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||||
|
|
||||||
|
// RoleService, RoleRepository
|
||||||
builder.Services.AddScoped<IRoleService, RoleService>();
|
builder.Services.AddScoped<IRoleService, RoleService>();
|
||||||
builder.Services.AddScoped<IRoleRepository, RoleRepository>();
|
builder.Services.AddScoped<IRoleRepository, RoleRepository>();
|
||||||
|
|
||||||
|
// AuthService
|
||||||
builder.Services.AddScoped<IAuthService, AuthService>();
|
builder.Services.AddScoped<IAuthService, AuthService>();
|
||||||
//builder.Services.AddScoped<IAuthRepository, AuthRepository>();
|
|
||||||
|
|
||||||
|
// TwoFactorAuthService, TwoFactorAuthReposittory
|
||||||
|
builder.Services.AddScoped<ITwoFactorAuthService, TwoFactorAuthService>();
|
||||||
|
builder.Services.AddScoped<ITwoFactorAuthRepository, TwoFactorAuthRepository>();
|
||||||
|
|
||||||
|
// DatabaseContext
|
||||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
{
|
{
|
||||||
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("Project.Web"));
|
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("Project.Web"));
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddMemoryCache();
|
builder.Services.AddMemoryCache();
|
||||||
|
|
||||||
|
// CookieAuth
|
||||||
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
.AddCookie(options =>
|
.AddCookie(options =>
|
||||||
{
|
{
|
||||||
@ -49,6 +61,7 @@ builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationSc
|
|||||||
options.LogoutPath = "/api/auth/logout";
|
options.LogoutPath = "/api/auth/logout";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Authorization
|
||||||
builder.Services.AddAuthorization(options =>
|
builder.Services.AddAuthorization(options =>
|
||||||
{
|
{
|
||||||
options.AddPolicy("AdminOnly", policy =>
|
options.AddPolicy("AdminOnly", policy =>
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="GoogleAuthenticator" Version="3.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user