From 4c01d1de5206a3e488b1316e60d02cc3cfdd738f Mon Sep 17 00:00:00 2001 From: CodeLiturgy Date: Sat, 10 Sep 2022 23:22:04 +0100 Subject: [PATCH] Working state --- .../ApplicationUserDbContext.cs | 48 ++--- BlueWest.Api/Context/ExchangeInterface.cs | 4 +- .../Controllers/ApplicationUserController.cs | 26 +++ BlueWest.Api/Controllers/AuthController.cs | 26 ++- BlueWest.Api/Controllers/CountryController.cs | 1 + .../Controllers/CurrencyController.cs | 3 +- BlueWest.Api/Controllers/FinanceController.cs | 1 + BlueWest.Api/Controllers/UserController.cs | 4 +- BlueWest.Api/StartupExtensions.cs | 7 +- ...erManager.cs => ApplicationUserManager.cs} | 7 +- BlueWest.Api/Users/Auth/AuthManager.cs | 2 +- BlueWest.Api/Users/Auth/AuthSettings.cs | 5 +- BlueWest.Api/Users/Auth/SignInManager.cs | 5 +- .../Users/Claims/ClaimsDbExtensions.cs | 8 + BlueWest.Api/Users/Constants.cs | 15 ++ BlueWest.Api/Users/Crypto/BaseCryptoItem.cs | 12 +- BlueWest.Api/Users/Crypto/Hasher.cs | 33 ++- BlueWest.Api/Users/Crypto/IHasher.cs | 24 ++- BlueWest.Api/Users/Crypto/SHA_512.cs | 19 +- BlueWest.Api/Users/Jwt/ITokenFactory.cs | 2 +- BlueWest.Api/Users/Jwt/JwtFactory.cs | 2 +- BlueWest.Api/Users/Jwt/JwtIssuerOptions.cs | 2 +- BlueWest.Api/Users/Jwt/JwtTokenHandler.cs | 18 +- .../Users/Models/RegisterViewModel.cs | 7 + .../Users/Models/ResetPasswordViewModel.cs | 15 ++ BlueWest.Api/Users/Roles/ApplicationRole.cs | 12 +- .../Users/Roles/ApplicationRoleClaim.cs | 7 + .../Users/Roles/ApplicationUserClaim.cs | 24 ++- .../Users/Roles/ApplicationUserRole.cs | 9 +- BlueWest.Api/Users/Roles/RoleStore.cs | 104 +--------- BlueWest.Api/Users/UserRepository.cs | 191 ++---------------- BlueWest.Frontend | 2 +- include/BlueWest.EfMethods | 2 +- 33 files changed, 303 insertions(+), 344 deletions(-) rename BlueWest.Api/{Users => Context}/ApplicationUserDbContext.cs (72%) create mode 100644 BlueWest.Api/Controllers/ApplicationUserController.cs rename BlueWest.Api/Users/{UserManager.cs => ApplicationUserManager.cs} (94%) create mode 100644 BlueWest.Api/Users/Claims/ClaimsDbExtensions.cs diff --git a/BlueWest.Api/Users/ApplicationUserDbContext.cs b/BlueWest.Api/Context/ApplicationUserDbContext.cs similarity index 72% rename from BlueWest.Api/Users/ApplicationUserDbContext.cs rename to BlueWest.Api/Context/ApplicationUserDbContext.cs index 9cee546..9a88c5b 100644 --- a/BlueWest.Api/Users/ApplicationUserDbContext.cs +++ b/BlueWest.Api/Context/ApplicationUserDbContext.cs @@ -1,15 +1,10 @@ -using System; -using System.Threading.Tasks; using BlueWest.Data; -using BlueWest.WebApi.EF; +using BlueWest.WebApi.Context.Users; using BlueWest.WebApi.EF.Model; -using Duende.IdentityServer.EntityFramework.Entities; -using Duende.IdentityServer.EntityFramework.Interfaces; -using Duende.IdentityServer.Stores.Serialization; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -namespace BlueWest.WebApi.Context.Users; +namespace BlueWest.WebApi.Context; /// /// Application User Db Context @@ -24,30 +19,27 @@ public class ApplicationUserDbContext : IdentityDbContext< ApplicationRoleClaim, ApplicationUserToken> { + /// + public sealed override DbSet UserClaims { get; set; } - /// - /// Configures the schema needed for the identity framework. - /// - /// - /// The builder being used to construct the model for this context. - /// - - /// - /// Database for the context of database users - /// - /// + /// + public sealed override DbSet UserRoles { get; set; } + + /// + public sealed override DbSet Roles { get; set; } + + /// + public sealed override DbSet RoleClaims { get; set; } + + + /// public ApplicationUserDbContext(DbContextOptions options) : base(options) { Database.EnsureCreated(); - } - /// - /// Configures the schema needed for the identity framework. - /// - /// - /// The builder being used to construct the model for this context. - /// + + /// protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); @@ -90,11 +82,15 @@ public class ApplicationUserDbContext : IdentityDbContext< b.HasKey(r => new { r.UserId, r.RoleId }); b.ToTable("UserRoles"); }); - + builder.Entity(b => b.HasOne() .WithMany(x => x.Users) .HasForeignKey(x => x.ApplicationUserId)); + builder.Entity().ToTable("RoleClaims"); + builder.Entity().ToTable("UserRole"); + + builder.ConfigureCurrentDbModel(); } diff --git a/BlueWest.Api/Context/ExchangeInterface.cs b/BlueWest.Api/Context/ExchangeInterface.cs index f87f6ed..6f074ff 100644 --- a/BlueWest.Api/Context/ExchangeInterface.cs +++ b/BlueWest.Api/Context/ExchangeInterface.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; using BlueWest.Tools; -using BlueWest.WebApi.Context.Users; +using BlueWest.WebApi.Context; using BlueWest.WebApi.EF; namespace BlueWest.WebApi.Interfaces @@ -9,7 +9,7 @@ namespace BlueWest.WebApi.Interfaces /// /// Empty constructor /// - + public struct ExchangeEvent { } /// /// Interface for getting and storing exchange rates data diff --git a/BlueWest.Api/Controllers/ApplicationUserController.cs b/BlueWest.Api/Controllers/ApplicationUserController.cs new file mode 100644 index 0000000..d3b1d9d --- /dev/null +++ b/BlueWest.Api/Controllers/ApplicationUserController.cs @@ -0,0 +1,26 @@ +using BlueWest.WebApi.Context; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace BlueWest.WebApi.Controllers +{ + [ApiController] + [Route("[controller]")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + public class ApplicationUserController : ControllerBase + { + private readonly ApplicationUserDbContext _context; + + public ApplicationUserController(ApplicationUserDbContext context) + { + _context = context; + } + + + } +} + diff --git a/BlueWest.Api/Controllers/AuthController.cs b/BlueWest.Api/Controllers/AuthController.cs index 27a1df4..10c5276 100644 --- a/BlueWest.Api/Controllers/AuthController.cs +++ b/BlueWest.Api/Controllers/AuthController.cs @@ -25,7 +25,6 @@ namespace BlueWest.WebApi.Controllers; /// /// /// - /// /// /// public AuthController( IAuthManager authManager, IUserManager userManager) @@ -48,6 +47,11 @@ namespace BlueWest.WebApi.Controllers; } + /// + /// Gets a bearer token + /// + /// + /// [AllowAnonymous] [HttpPost("login")] public async Task> GetTokenAsync(LoginViewModel loginViewModel) @@ -63,8 +67,13 @@ namespace BlueWest.WebApi.Controllers; } + /// + /// Do Cookie based login. + /// + /// + /// [AllowAnonymous] - [HttpPost("login2")] + [HttpPost("logincookie")] public async Task> DoLoginAsync(LoginViewModel loginDto) { var user = await _userManager.FindByEmailAsync(loginDto.Email); @@ -83,6 +92,11 @@ namespace BlueWest.WebApi.Controllers; return Json(false); } + /// + /// Do Cookie based logout + /// + /// + /// [AllowAnonymous] [HttpPost("logout")] public async Task> DoLogoutAsync(LoginViewModel loginDto) @@ -90,13 +104,5 @@ namespace BlueWest.WebApi.Controllers; await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Json(true); } - - [HttpGet("test")] - public ActionResult TestRequest() - { - return Ok(new {Message = "Test"}); - } - - } \ No newline at end of file diff --git a/BlueWest.Api/Controllers/CountryController.cs b/BlueWest.Api/Controllers/CountryController.cs index 187af15..7a61d99 100644 --- a/BlueWest.Api/Controllers/CountryController.cs +++ b/BlueWest.Api/Controllers/CountryController.cs @@ -19,6 +19,7 @@ namespace BlueWest.WebApi.Controllers [Route("[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + [Authorize(Roles = "Administrator")] public class CountryController : ControllerBase { diff --git a/BlueWest.Api/Controllers/CurrencyController.cs b/BlueWest.Api/Controllers/CurrencyController.cs index 3d4ec82..8484ec8 100644 --- a/BlueWest.Api/Controllers/CurrencyController.cs +++ b/BlueWest.Api/Controllers/CurrencyController.cs @@ -17,7 +17,8 @@ namespace BlueWest.WebApi.Controllers [ApiController] [Route("[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + [Authorize(Roles = "Administrator")] public partial class CurrencyController : ControllerBase { diff --git a/BlueWest.Api/Controllers/FinanceController.cs b/BlueWest.Api/Controllers/FinanceController.cs index d10c57d..13dc7cb 100644 --- a/BlueWest.Api/Controllers/FinanceController.cs +++ b/BlueWest.Api/Controllers/FinanceController.cs @@ -16,6 +16,7 @@ namespace BlueWest.WebApi.Controllers; [Route("[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] +[Authorize(Roles = "Administrator")] public class FinanceController : ControllerBase { private readonly FinanceDbContext _dbContext; diff --git a/BlueWest.Api/Controllers/UserController.cs b/BlueWest.Api/Controllers/UserController.cs index e91d349..3c63e1a 100644 --- a/BlueWest.Api/Controllers/UserController.cs +++ b/BlueWest.Api/Controllers/UserController.cs @@ -18,7 +18,9 @@ namespace BlueWest.WebApi.Controllers [ApiController] [Route("[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] + [Authorize(Roles = "Administrator")] + public class UserController : ControllerBase { diff --git a/BlueWest.Api/StartupExtensions.cs b/BlueWest.Api/StartupExtensions.cs index d882eaa..0bffff7 100644 --- a/BlueWest.Api/StartupExtensions.cs +++ b/BlueWest.Api/StartupExtensions.cs @@ -3,6 +3,7 @@ using System.Text; using System.Threading.Tasks; using BlueWest.Cryptography; using BlueWest.Data; +using BlueWest.WebApi.Context; using BlueWest.WebApi.Context.Users; using BlueWest.WebApi.EF; using Microsoft.AspNetCore.Authentication; @@ -104,7 +105,7 @@ namespace BlueWest.WebApi } - public static IServiceCollection AddAuthServerServices(this IServiceCollection services, string origins, IConfiguration configuration , IWebHostEnvironment environment) + internal static IServiceCollection AddAuthServerServices(this IServiceCollection services, string origins, IConfiguration configuration , IWebHostEnvironment environment) { services.AddScoped(); @@ -113,13 +114,13 @@ namespace BlueWest.WebApi services .AddScoped< UserRepository>() - .AddScoped() + .AddScoped() .AddScoped() .AddScoped(); services .AddIdentityCore(opt => { opt.User.RequireUniqueEmail = true; }) - .AddUserManager() + .AddUserManager() .AddUserStore(); // Database Context and Swagger diff --git a/BlueWest.Api/Users/UserManager.cs b/BlueWest.Api/Users/ApplicationUserManager.cs similarity index 94% rename from BlueWest.Api/Users/UserManager.cs rename to BlueWest.Api/Users/ApplicationUserManager.cs index a7d0617..fac7d11 100644 --- a/BlueWest.Api/Users/UserManager.cs +++ b/BlueWest.Api/Users/ApplicationUserManager.cs @@ -10,11 +10,14 @@ using Microsoft.Extensions.Options; namespace BlueWest.WebApi.Context.Users; -public class UserManager : UserManager, IUserManager +/// +/// User Manager Object +/// +internal class ApplicationUserManager : UserManager, IUserManager { private readonly IHasher _hasher; private readonly UserRepository _usersRepo; - public UserManager(UserRepository store, IOptions optionsAccessor, + public ApplicationUserManager(UserRepository store, IOptions optionsAccessor, IHasher passwordHasher, IEnumerable> userValidators, IEnumerable> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger> logger) : base(store, diff --git a/BlueWest.Api/Users/Auth/AuthManager.cs b/BlueWest.Api/Users/Auth/AuthManager.cs index 2bd44e3..b4731a8 100644 --- a/BlueWest.Api/Users/Auth/AuthManager.cs +++ b/BlueWest.Api/Users/Auth/AuthManager.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Identity; namespace BlueWest.WebApi.Context.Users; -public class AuthManager : IAuthManager +internal class AuthManager : IAuthManager { private readonly IUserManager _userManager; private readonly UserRepository _usersRepo; diff --git a/BlueWest.Api/Users/Auth/AuthSettings.cs b/BlueWest.Api/Users/Auth/AuthSettings.cs index bce65bc..78ebf42 100644 --- a/BlueWest.Api/Users/Auth/AuthSettings.cs +++ b/BlueWest.Api/Users/Auth/AuthSettings.cs @@ -2,5 +2,8 @@ namespace BlueWest.WebApi.Context.Users; public class AuthSettings { - public string SecretKey { get; set; } + /// + /// SecretKey + /// + public string SecretKey { get; set; } } \ No newline at end of file diff --git a/BlueWest.Api/Users/Auth/SignInManager.cs b/BlueWest.Api/Users/Auth/SignInManager.cs index 0ae9b7a..bae6ae4 100644 --- a/BlueWest.Api/Users/Auth/SignInManager.cs +++ b/BlueWest.Api/Users/Auth/SignInManager.cs @@ -27,10 +27,7 @@ internal class SignInManager : SignInManager { } - - public override async Task CreateUserPrincipalAsync(ApplicationUser user) => await ClaimsFactory.CreateAsync(user); - - + } \ No newline at end of file diff --git a/BlueWest.Api/Users/Claims/ClaimsDbExtensions.cs b/BlueWest.Api/Users/Claims/ClaimsDbExtensions.cs new file mode 100644 index 0000000..a3ef2fd --- /dev/null +++ b/BlueWest.Api/Users/Claims/ClaimsDbExtensions.cs @@ -0,0 +1,8 @@ +namespace BlueWest.WebApi.Context.Users + +{ + internal class ClaimsDbExtensions + { + } +} + diff --git a/BlueWest.Api/Users/Constants.cs b/BlueWest.Api/Users/Constants.cs index b0bae0b..8315168 100644 --- a/BlueWest.Api/Users/Constants.cs +++ b/BlueWest.Api/Users/Constants.cs @@ -2,16 +2,31 @@ namespace BlueWest.WebApi.Context.Users; public static class Constants { + /// + /// AdminRoleName + /// public const string AdminRoleName = "Admin"; + /// + /// UserRoleName + /// public const string UserRoleName = "User"; public const string ExpectatorRoleName = "Expectator"; + /// + /// JwtClaimIdentifiers + /// public static class JwtClaimIdentifiers { public const string Rol = "rol", Id = "id"; } + /// + /// JwtClaims + /// public static class JwtClaims { + /// + /// JwtClaims.ApiAccess + /// public const string ApiAccess = "api_access"; } } \ No newline at end of file diff --git a/BlueWest.Api/Users/Crypto/BaseCryptoItem.cs b/BlueWest.Api/Users/Crypto/BaseCryptoItem.cs index 7d103bc..103159a 100644 --- a/BlueWest.Api/Users/Crypto/BaseCryptoItem.cs +++ b/BlueWest.Api/Users/Crypto/BaseCryptoItem.cs @@ -5,7 +5,7 @@ using System.Text; namespace BlueWest.Cryptography { - public abstract class BaseCryptoItem + internal abstract class BaseCryptoItem { public enum HashAlgorithm { @@ -19,6 +19,11 @@ namespace BlueWest.Cryptography SHA3_512 = 3 } + /// + /// HexStringToByteArray + /// + /// + /// protected byte[] HexStringToByteArray(string stringInHexFormat) { var converted = Enumerable.Range(0, stringInHexFormat.Length) @@ -29,6 +34,11 @@ namespace BlueWest.Cryptography return converted; } + /// + /// ByteArrayToString + /// + /// + /// protected string ByteArrayToString(byte[] bytes) { var sb = new StringBuilder(); diff --git a/BlueWest.Api/Users/Crypto/Hasher.cs b/BlueWest.Api/Users/Crypto/Hasher.cs index 93edf71..f6d5ad8 100644 --- a/BlueWest.Api/Users/Crypto/Hasher.cs +++ b/BlueWest.Api/Users/Crypto/Hasher.cs @@ -8,20 +8,35 @@ using Microsoft.AspNetCore.Identity; namespace BlueWest.Cryptography { - public class Hasher : BaseCryptoItem, IHasher + /// + /// Hasher + /// + internal class Hasher : BaseCryptoItem, IHasher { private const int SaltLength = 64; + /// + /// CreateHash + /// + /// + /// + /// public string CreateHash(string text, BaseCryptoItem.HashAlgorithm algorithm) { var salt = CreateRandomString(SaltLength); return CreateHash(text, salt, algorithm, true); } + /// + /// CreateHash + /// + /// + /// + /// + /// public string CreateHash(string text, string saltName, BaseCryptoItem.HashAlgorithm algorithm) { - var salt = "TODOFIXME"; - return CreateHash(text, salt, algorithm, false); + return CreateHash(text, saltName, algorithm, false); } private string CreateHash(string text, string salt, HashAlgorithm algorithm, bool storeSalt) @@ -45,6 +60,12 @@ namespace BlueWest.Cryptography return hash; } + /// + /// Check for a matching hash. + /// + /// + /// + /// public bool MatchesHash(string text, string hash) { string salt = ""; @@ -58,6 +79,12 @@ namespace BlueWest.Cryptography return hashed == hash; } + /// + /// Hash password + /// + /// + /// + /// public string HashPassword(ApplicationUser ApplicationUser, string password) { return CreateHash(password, HashAlgorithm.SHA3_512); diff --git a/BlueWest.Api/Users/Crypto/IHasher.cs b/BlueWest.Api/Users/Crypto/IHasher.cs index 258badc..30fbec4 100644 --- a/BlueWest.Api/Users/Crypto/IHasher.cs +++ b/BlueWest.Api/Users/Crypto/IHasher.cs @@ -4,9 +4,31 @@ using Microsoft.AspNetCore.Identity; namespace BlueWest.Cryptography; -public interface IHasher : IPasswordHasher +/// +/// IHasher contract +/// +internal interface IHasher : IPasswordHasher { + /// + /// Create hash + /// + /// + /// + /// string CreateHash(string text, BaseCryptoItem.HashAlgorithm algorithm); + /// + /// Create hash + /// + /// + /// + /// + /// string CreateHash(string text, string salt, BaseCryptoItem.HashAlgorithm algorithm); + /// + /// MatchesHash + /// + /// + /// + /// bool MatchesHash(string text, string hash); } \ No newline at end of file diff --git a/BlueWest.Api/Users/Crypto/SHA_512.cs b/BlueWest.Api/Users/Crypto/SHA_512.cs index a7f0a99..999a711 100644 --- a/BlueWest.Api/Users/Crypto/SHA_512.cs +++ b/BlueWest.Api/Users/Crypto/SHA_512.cs @@ -3,8 +3,18 @@ using System.Text; using Microsoft.AspNetCore.Cryptography.KeyDerivation; namespace BlueWest.Cryptography { - public class SHA2_512 : BaseCryptoItem + /// + /// SHA2_512 : BaseCryptoItem + /// + internal class SHA2_512 : BaseCryptoItem { + /// + /// Hash with the provided salt + /// + /// + /// + /// + /// public string Hash(string text, string salt, bool storeSalt) { var fullText = string.Concat(text, salt); @@ -25,6 +35,13 @@ namespace BlueWest.Cryptography } + /// + /// Hash_PBKDF2 algorithm. + /// + /// + /// + /// + /// public string Hash_PBKDF2(string plainText, string salt, bool saveSaltInResult) { var saltAsBytes = Encoding.ASCII.GetBytes(salt); diff --git a/BlueWest.Api/Users/Jwt/ITokenFactory.cs b/BlueWest.Api/Users/Jwt/ITokenFactory.cs index 1bdfeda..392e198 100644 --- a/BlueWest.Api/Users/Jwt/ITokenFactory.cs +++ b/BlueWest.Api/Users/Jwt/ITokenFactory.cs @@ -1,6 +1,6 @@ namespace BlueWest.WebApi.Context.Users; -public interface ITokenFactory +internal interface ITokenFactory { string GenerateToken(int size= 32); } \ No newline at end of file diff --git a/BlueWest.Api/Users/Jwt/JwtFactory.cs b/BlueWest.Api/Users/Jwt/JwtFactory.cs index 1d1be6c..948f7ad 100644 --- a/BlueWest.Api/Users/Jwt/JwtFactory.cs +++ b/BlueWest.Api/Users/Jwt/JwtFactory.cs @@ -8,7 +8,7 @@ using static BlueWest.WebApi.Context.Users.Constants; namespace BlueWest.WebApi.Context.Users; -public class JwtFactory : IJwtFactory +internal class JwtFactory : IJwtFactory { private readonly IJwtTokenHandler _jwtTokenHandler; private readonly JwtIssuerOptions _jwtOptions; diff --git a/BlueWest.Api/Users/Jwt/JwtIssuerOptions.cs b/BlueWest.Api/Users/Jwt/JwtIssuerOptions.cs index 6a00e15..530e5a5 100644 --- a/BlueWest.Api/Users/Jwt/JwtIssuerOptions.cs +++ b/BlueWest.Api/Users/Jwt/JwtIssuerOptions.cs @@ -4,7 +4,7 @@ using Microsoft.IdentityModel.Tokens; namespace BlueWest.WebApi.Context.Users; -public class JwtIssuerOptions +internal class JwtIssuerOptions { /// /// 4.1.1. "iss" (Issuer) Claim - The "iss" (issuer) claim identifies the principal that issued the JWT. diff --git a/BlueWest.Api/Users/Jwt/JwtTokenHandler.cs b/BlueWest.Api/Users/Jwt/JwtTokenHandler.cs index 956c079..54820c9 100644 --- a/BlueWest.Api/Users/Jwt/JwtTokenHandler.cs +++ b/BlueWest.Api/Users/Jwt/JwtTokenHandler.cs @@ -9,17 +9,31 @@ public class JwtTokenHandler : IJwtTokenHandler { private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler; + /// + /// JwtTokenHandler + /// public JwtTokenHandler() { - if (_jwtSecurityTokenHandler == null) - _jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); + _jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); } + /// + /// Write token + /// + /// + /// public string WriteToken(JwtSecurityToken jwt) { return _jwtSecurityTokenHandler.WriteToken(jwt); } + /// + /// Validate Token + /// + /// + /// + /// + /// public ClaimsPrincipal ValidateToken(string token, TokenValidationParameters tokenValidationParameters) { try diff --git a/BlueWest.Api/Users/Models/RegisterViewModel.cs b/BlueWest.Api/Users/Models/RegisterViewModel.cs index 1fafc3a..d599d3c 100644 --- a/BlueWest.Api/Users/Models/RegisterViewModel.cs +++ b/BlueWest.Api/Users/Models/RegisterViewModel.cs @@ -23,6 +23,9 @@ public class RegisterViewModel [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } + /// + /// Username + /// public string Username { get; set; } /// @@ -33,6 +36,10 @@ public class RegisterViewModel [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } + /// + /// Convert RegisterViewModel to ApplicationUser + /// + /// public ApplicationUser ToUser() { var newUser = new ApplicationUser(); diff --git a/BlueWest.Api/Users/Models/ResetPasswordViewModel.cs b/BlueWest.Api/Users/Models/ResetPasswordViewModel.cs index 94a7674..d00d7ac 100644 --- a/BlueWest.Api/Users/Models/ResetPasswordViewModel.cs +++ b/BlueWest.Api/Users/Models/ResetPasswordViewModel.cs @@ -2,21 +2,36 @@ using System.ComponentModel.DataAnnotations; namespace BlueWest.WebApi.Context.Users; +/// +/// Reset password view model +/// public class ResetPasswordViewModel { + /// + /// Email address from which the password needs to be reset. + /// [Required] [EmailAddress] public string Email { get; set; } + /// + /// Password + /// [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] public string Password { get; set; } + /// + /// Password confirmation + /// [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } + /// + /// The code to reset password. + /// public string Code { get; set; } } \ No newline at end of file diff --git a/BlueWest.Api/Users/Roles/ApplicationRole.cs b/BlueWest.Api/Users/Roles/ApplicationRole.cs index 8b00c88..f65b5b9 100644 --- a/BlueWest.Api/Users/Roles/ApplicationRole.cs +++ b/BlueWest.Api/Users/Roles/ApplicationRole.cs @@ -4,6 +4,16 @@ namespace BlueWest.WebApi.Context.Users { /// public class ApplicationRole : IdentityRole - { } + { + /// + public sealed override string Id { get; set; } + + /// + public sealed override string Name { get; set; } + + /// + public sealed override string NormalizedName { get; set; } + + } } diff --git a/BlueWest.Api/Users/Roles/ApplicationRoleClaim.cs b/BlueWest.Api/Users/Roles/ApplicationRoleClaim.cs index 2e88895..f4be47f 100644 --- a/BlueWest.Api/Users/Roles/ApplicationRoleClaim.cs +++ b/BlueWest.Api/Users/Roles/ApplicationRoleClaim.cs @@ -6,5 +6,12 @@ namespace BlueWest.WebApi.Context.Users; /// public class ApplicationRoleClaim : IdentityRoleClaim { + + public sealed override int Id { get; set; } + public sealed override string RoleId { get; set; } + + public sealed override string ClaimType { get; set; } + + public sealed override string ClaimValue { get; set; } } \ No newline at end of file diff --git a/BlueWest.Api/Users/Roles/ApplicationUserClaim.cs b/BlueWest.Api/Users/Roles/ApplicationUserClaim.cs index 493de3c..710b315 100644 --- a/BlueWest.Api/Users/Roles/ApplicationUserClaim.cs +++ b/BlueWest.Api/Users/Roles/ApplicationUserClaim.cs @@ -5,5 +5,27 @@ namespace BlueWest.WebApi.Context.Users; /// public class ApplicationUserClaim : IdentityUserClaim { - + /// + public sealed override int Id { get; set; } + + /// + public sealed override string UserId { get; set; } + + /// + public sealed override string ClaimType { get; set; } + + /// + public sealed override string ClaimValue { get; set; } + + public ApplicationUserClaim(ApplicationUserClaim applicationUserClaim) + { + Id = applicationUserClaim.Id; + UserId = applicationUserClaim.UserId; + ClaimType = applicationUserClaim.ClaimType; + ClaimValue = applicationUserClaim.ClaimValue; + } + + public ApplicationUserClaim() + { + } } \ No newline at end of file diff --git a/BlueWest.Api/Users/Roles/ApplicationUserRole.cs b/BlueWest.Api/Users/Roles/ApplicationUserRole.cs index 41f2c5a..001cfee 100644 --- a/BlueWest.Api/Users/Roles/ApplicationUserRole.cs +++ b/BlueWest.Api/Users/Roles/ApplicationUserRole.cs @@ -4,4 +4,11 @@ using Microsoft.AspNetCore.Identity; namespace BlueWest.WebApi.Context.Users; /// -public class ApplicationUserRole : IdentityUserRole { } \ No newline at end of file +public class ApplicationUserRole : IdentityUserRole +{ + /// + public sealed override string UserId { get; set; } + + /// + public sealed override string RoleId { get; set; } +} \ No newline at end of file diff --git a/BlueWest.Api/Users/Roles/RoleStore.cs b/BlueWest.Api/Users/Roles/RoleStore.cs index 3d9c5a7..effeac8 100644 --- a/BlueWest.Api/Users/Roles/RoleStore.cs +++ b/BlueWest.Api/Users/Roles/RoleStore.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace BlueWest.WebApi.Context.Users; @@ -10,104 +11,7 @@ namespace BlueWest.WebApi.Context.Users; /// /// Role storage management /// -public class RoleStore : IRoleStore +/*public class RoleStore : RoleStore { - private ApplicationUserDbContext _dbContext; - - /// - /// Role Store constructor - /// - /// - public RoleStore(ApplicationUserDbContext dbContext) - { - _dbContext = dbContext; - } - /// - /// - /// - /// - public void Dispose() - { - _dbContext = null; - } - - - /// - /// Get role name - /// - /// - /// - /// - /// - public async Task GetRoleNameAsync(ApplicationUserRole role, CancellationToken cancellationToken) - { - var foundRole = await _dbContext.Roles - .FirstOrDefaultAsync(x => x.Id == role.RoleId, cancellationToken: cancellationToken); - - if (foundRole != null) - { - return foundRole.Name; - } - - return string.Empty; - } - - - public async Task CreateAsync(ApplicationRole role, CancellationToken cancellationToken) - { - _dbContext.Roles.Add(role); - return await _dbContext.SaveChangesAsync(cancellationToken) >= 0 ? IdentityResult.Success : IdentityResult.Failed(); - } - - public async Task UpdateAsync(ApplicationRole role, CancellationToken cancellationToken) - { - _dbContext.Roles.Update(role); - return await _dbContext.SaveChangesAsync(cancellationToken) >= 0 ? IdentityResult.Success : IdentityResult.Failed(); - } - - public async Task DeleteAsync(ApplicationRole role, CancellationToken cancellationToken) - { - _dbContext.Roles.Remove(role); - return await _dbContext.SaveChangesAsync(cancellationToken) >= 0 ? IdentityResult.Success : IdentityResult.Failed(); - } - - public async Task GetRoleIdAsync(ApplicationRole role, CancellationToken cancellationToken) - { - var x = await _dbContext.Roles.FirstOrDefaultAsync(x => x.Id == role.Id, cancellationToken: cancellationToken); - if (x != null) - { - return x.Id; - } - return string.Empty; - } - - public Task GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task FindByIdAsync(string roleId, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public Task FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } -} \ No newline at end of file + +}*/ \ No newline at end of file diff --git a/BlueWest.Api/Users/UserRepository.cs b/BlueWest.Api/Users/UserRepository.cs index e6aaf4c..c3362b2 100644 --- a/BlueWest.Api/Users/UserRepository.cs +++ b/BlueWest.Api/Users/UserRepository.cs @@ -13,10 +13,23 @@ namespace BlueWest.WebApi.Context.Users; /// /// Users Repository /// -public class UserRepository : UserStore +public class UserRepository : UserStore { private readonly ApplicationUserDbContext _context; + /// + /// User repository + /// + /// + /// public UserRepository(ApplicationUserDbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { _context = context; @@ -32,137 +45,6 @@ public class UserRepository : UserStore - /// Create Application User - /// - /// - /*public override async Task CreateAsync(ApplicationUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } - await _context.AddAsync(user, cancellationToken); - await _context.SaveChangesAsync(cancellationToken); - return IdentityResult.Success; - }*/ - /// - /// Save Changes - /// - /* - public async Task SaveChanges() - { - await _context.SaveChangesAsync(); - } - */ - - /* - private async Task SaveChanges(ApplicationUser user) - { - _context.Users.Update(user); - return await _context.SaveChangesAsync() > 0; - } - */ - - - /// - /// Dispose repository - /// - /* - public void Dispose() - { - _context.Dispose(); - } - */ - - /* - /// - public override Task GetUserIdAsync(ApplicationUser user, CancellationToken cancellationToken = default) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.Id.ToString()); - - } - - /// - public override Task GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.UserName); - } - */ - - /// - /* - public override async Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken) - { - var foundUser = await _context.Users.FirstOrDefaultAsync(x => x.Id == user.Id, cancellationToken: cancellationToken); - if (foundUser == null) return; - foundUser.UserName = userName; - await SaveChanges(user); - } - */ - - /* - /// - public override Task GetNormalizedUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.NormalizedUserName); - - } - - - /// - public override async Task UpdateAsync(ApplicationUser user, CancellationToken cancellationToken) - { - _context.Users.Update(user); - - var success = await _context.SaveChangesAsync(cancellationToken) > 0; - - if (success) return IdentityResult.Success; - - return IdentityResult.Failed(); - } - - /// - public override async Task DeleteAsync(ApplicationUser user, CancellationToken cancellationToken) - { - var foundUser = await _context.Users.FirstOrDefaultAsync(x=> x.Id == user.Id, cancellationToken: cancellationToken); - - var error = new IdentityError {Description = "ApplicationUser Not found"}; - - if (foundUser == null) return IdentityResult.Failed(error); - - _context.Users.Remove(foundUser); - - return IdentityResult.Success; - } - - /// - public async Task GetUserById(string id) - { - var db = _context.Users; - var user = await db.FirstOrDefaultAsync(u => u.Id.ToString() == id); - return user; - } - */ - - /// public override Task GetPasswordHashAsync(ApplicationUser user, CancellationToken cancellationToken = default) { @@ -185,49 +67,4 @@ public class UserRepository : UserStore - public override Task GetEmailAsync(ApplicationUser user, CancellationToken cancellationToken = default) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.Email); - } - - /// - public override Task GetEmailConfirmedAsync(ApplicationUser user, CancellationToken cancellationToken = default) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.EmailConfirmed); - } - - /// - public override async Task FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken = default) - { - ApplicationUser user = null; - var db = _context.Users; - user = await db.FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail, cancellationToken: cancellationToken); - return user; - } - - /// - public override Task GetNormalizedEmailAsync(ApplicationUser user, CancellationToken cancellationToken = default) - { - base.GetNormalizedEmailAsync(user, cancellationToken); - - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - return Task.FromResult(user.NormalizedEmail); - }*/ - } \ No newline at end of file diff --git a/BlueWest.Frontend b/BlueWest.Frontend index f7249c3..b6750d7 160000 --- a/BlueWest.Frontend +++ b/BlueWest.Frontend @@ -1 +1 @@ -Subproject commit f7249c3bb1ac4fd12a6bdd83f902733530d04bc7 +Subproject commit b6750d7128057b72e5ab97ee9ff602abe80d334b diff --git a/include/BlueWest.EfMethods b/include/BlueWest.EfMethods index 2ac7524..6fd065f 160000 --- a/include/BlueWest.EfMethods +++ b/include/BlueWest.EfMethods @@ -1 +1 @@ -Subproject commit 2ac7524e8bc6c5f8430e944958e0890b090a4a55 +Subproject commit 6fd065fc4798699394837e770d087ef110aa8e55