Credentials working in the frontend

This commit is contained in:
Wvader 2022-09-12 15:57:37 +01:00
parent 7e4bf4e5cf
commit e0e9df2edd
18 changed files with 307 additions and 130 deletions

View File

@ -22,21 +22,26 @@ namespace BlueWest.WebApi.Context
ApplicationUserToken> ApplicationUserToken>
{ {
/// <inheritdoc /> /// <inheritdoc />
[EfGetMany(typeof(ApplicationUserClaim))] [EfGetMany(typeof(ApplicationUserClaimUnique))]
public sealed override DbSet<ApplicationUserClaim> UserClaims { get; set; } public sealed override DbSet<ApplicationUserClaim> UserClaims { get; set; }
[EfGetMany(typeof(ApplicationUserRole))] [EfGetMany(typeof(ApplicationUserRoleUnique))]
/// <inheritdoc /> /// <inheritdoc />
public sealed override DbSet<ApplicationUserRole> UserRoles { get; set; } public sealed override DbSet<ApplicationUserRole> UserRoles { get; set; }
[EfGetMany(typeof(ApplicationRole))] [EfGetMany(typeof(ApplicationRoleUnique))]
/// <inheritdoc /> /// <inheritdoc />
public sealed override DbSet<ApplicationRole> Roles { get; set; } public sealed override DbSet<ApplicationRole> Roles { get; set; }
[EfGetMany(typeof(ApplicationRoleClaim))] [EfGetMany(typeof(ApplicationRoleClaimUnique))]
/// <inheritdoc /> /// <inheritdoc />
public sealed override DbSet<ApplicationRoleClaim> RoleClaims { get; set; } public sealed override DbSet<ApplicationRoleClaim> RoleClaims { get; set; }
[EfGetMany(typeof(ApplicationUserUnique))]
[EfUpdateMethods( updateType: typeof(ApplicationUserUnique), returnType: typeof(ApplicationUserUnique), keyPropertyMemberName: nameof(ApplicationUserUnique.Id))]
public sealed override DbSet<ApplicationUser> Users { get; set; }
#region Initialization
/// <inheritdoc /> /// <inheritdoc />
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options) : base(options) public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options) : base(options)
@ -76,6 +81,11 @@ namespace BlueWest.WebApi.Context
b.HasMany<ApplicationRoleClaim>().WithOne().HasForeignKey(rc => rc.RoleId).IsRequired(); b.HasMany<ApplicationRoleClaim>().WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
}); });
builder.Entity<ApplicationUserRole>().HasOne<ApplicationRole>(x => x.ApplicationRole);
builder.Entity<ApplicationRoleClaim>().HasOne<ApplicationRole>(x => x.ApplicationRole);
builder.Entity<ApplicationUserClaim>().HasOne<ApplicationUser>(x => x.ApplicationUser);
builder.Entity<ApplicationRoleClaim>(b => builder.Entity<ApplicationRoleClaim>(b =>
{ {
b.HasKey(rc => rc.Id); b.HasKey(rc => rc.Id);
@ -98,5 +108,9 @@ namespace BlueWest.WebApi.Context
builder.ConfigureCurrentDbModel(); builder.ConfigureCurrentDbModel();
} }
#endregion
/// <inheritdoc />
} }
} }

View File

@ -1,26 +1,131 @@
using BlueWest.Data;
using BlueWest.WebApi.Context; using BlueWest.WebApi.Context;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace BlueWest.WebApi.Controllers namespace BlueWest.WebApi.Controllers
{ {
[ApiController] [ApiController]
[Route("[controller]")] [Route("application/users")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
[EnableCors(Constants.CorsPolicyName)]
public class ApplicationUserController : ControllerBase public class ApplicationUserController : ControllerBase
{ {
private readonly ApplicationUserDbContext _context; private readonly ApplicationUserDbContext _dbContext;
public ApplicationUserController(ApplicationUserDbContext context) public ApplicationUserController(ApplicationUserDbContext context)
{ {
_context = context; _dbContext = context;
} }
#region Users
/// <summary>
/// Get Application users
/// </summary>
/// <returns></returns>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpGet]
public ActionResult GetApplicationUsers(
int skip = 0,
int take = 50,
int orderDir = 1)
{
var (success, users) = _dbContext.GetUsers( skip, take, orderDir);
if (!success) return new NotFoundResult();
return Ok(users);
}
/// <summary>
/// Updates a User
/// </summary>
/// <param name="UserCode">The UserId ISO 3166 code</param>
/// <param name="UserToUpdate">User payload data</param>
/// <returns></returns>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[HttpPut("{UserCode}")]
public ActionResult UpdateApplicationUser(int UserCode, UserUnique UserToUpdate)
{
//var (success, User) = _dbContext.UpdateUser(UserToUpdate, UserCode);
/*
if (success)
{
return Ok(User);
}
*/
return new NotFoundResult();
}
#endregion
/*
#region GetUserById
/// <summary>
/// Get User by Id
/// </summary>
/// <param name="UserId">ISO 3166-1 UserId numeric code</param>
/// <returns></returns>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpGet("{UserId}", Name = nameof(GetUserById))]
public ActionResult GetUserById(int UserId)
{
var (success, User) = _dbContext.GetOneUserById(UserId);
if (success)
{
return Ok(User);
}
return new NotFoundResult();
}
#endregion
*/
#region Roles
/// <summary>
/// Get Application users
/// </summary>
/// <returns></returns>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpGet("roles")]
public ActionResult GetApplicationRoles(
int skip = 0,
int take = 50,
int orderDir = 1)
{
var (success, users) = _dbContext.GetRoles( skip, take, orderDir);
if (!success) return new NotFoundResult();
return Ok(users);
}
#endregion
} }
} }
public static class Constants
{
public const string CorsPolicyName = "_myAllowSpecificOrigins";
}

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -17,7 +18,8 @@ namespace BlueWest.WebApi.Controllers;
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
[ApiController] [ApiController]
public class AuthController : Controller [EnableCors(Constants.CorsPolicyName)]
public class AuthController : Controller
{ {
private readonly IAuthManager _authManager; private readonly IAuthManager _authManager;
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
@ -85,11 +87,11 @@ namespace BlueWest.WebApi.Controllers;
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email)); identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
return Json(true); return Ok(new {authenticated = true});
} }
} }
return Json(false); return Ok(new {authenticated = false});
} }
/// <summary> /// <summary>

View File

@ -7,6 +7,7 @@ using BlueWest.WebApi.EF;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -19,7 +20,8 @@ namespace BlueWest.WebApi.Controllers
[Route("[controller]")] [Route("[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
[Authorize(Roles = "Administrator")] [EnableCors(Constants.CorsPolicyName)]
// [Authorize(Roles = "Administrator")]
public class CountryController : ControllerBase public class CountryController : ControllerBase
{ {

View File

@ -18,7 +18,7 @@ namespace BlueWest.WebApi.Controllers
[Route("[controller]")] [Route("[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
[Authorize(Roles = "Administrator")] // [Authorize(Roles = "Administrator")]
public partial class CurrencyController : ControllerBase public partial class CurrencyController : ControllerBase
{ {

View File

@ -24,7 +24,7 @@ namespace BlueWest.WebApi
{ {
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly IWebHostEnvironment _environment; private readonly IWebHostEnvironment _environment;
private readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; private readonly string MyAllowSpecificOrigins = Constants.CorsPolicyName;
/// <summary> /// <summary>
/// Startup configuration of the API /// Startup configuration of the API
@ -47,8 +47,10 @@ namespace BlueWest.WebApi
options.AddPolicy(name: MyAllowSpecificOrigins, options.AddPolicy(name: MyAllowSpecificOrigins,
builder => builder =>
{ {
builder.WithOrigins("http://127.0.0.1:5173", "localhost:5173", "127.0.0.1:5173") builder.WithOrigins("http://127.0.0.1:5173", "http://localhost:5173", "http://127.0.0.1:5173")
.AllowAnyHeader().AllowAnyMethod(); .AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}); });
}); });

View File

@ -170,7 +170,7 @@ namespace BlueWest.WebApi
}) })
.AddCookie(options => .AddCookie(options =>
{ {
options.LoginPath = "/api/auth/login"; options.LoginPath = "/api/auth/logincookie";
options.LogoutPath = "/api/auth/logout"; options.LogoutPath = "/api/auth/logout";
}) })
.AddJwtBearer(configureOptions => .AddJwtBearer(configureOptions =>
@ -198,8 +198,9 @@ namespace BlueWest.WebApi
services.AddAuthorization(options => services.AddAuthorization(options =>
{ {
options.AddPolicy("ApiUser", options.AddPolicy("ApiUser",
policy => policy.RequireClaim(Constants.JwtClaimIdentifiers.Rol, policy => policy.RequireClaim(Context.Users.Constants.JwtClaimIdentifiers.Rol,
Constants.JwtClaims.ApiAccess)); Context.Users.Constants.JwtClaims.ApiAccess));
}); });
// add identity // add identity

View File

@ -1,9 +1,12 @@
using MapTo;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace BlueWest.WebApi.Context.Users namespace BlueWest.WebApi.Context.Users
{ {
/// <inheritdoc /> /// <inheritdoc />
public class ApplicationRole : IdentityRole<string> [MapFrom(typeof(ApplicationRoleUnique))]
public partial class ApplicationRole : IdentityRole<string>
{ {
/// <inheritdoc /> /// <inheritdoc />
public sealed override string Id { get; set; } public sealed override string Id { get; set; }
@ -14,12 +17,6 @@ namespace BlueWest.WebApi.Context.Users
/// <inheritdoc /> /// <inheritdoc />
public sealed override string NormalizedName { get; set; } public sealed override string NormalizedName { get; set; }
public ApplicationRole(ApplicationRole applicationRole)
{
Id = applicationRole.Id;
Name = applicationRole.Name;
NormalizedName = applicationRole.NormalizedName;
}
} }
} }

View File

@ -0,0 +1,13 @@
using MapTo;
namespace BlueWest.WebApi.Context.Users
{
[MapFrom(typeof(ApplicationRole))]
public partial class ApplicationRoleUnique
{
public string Id { get; set; }
public string Name { get; set; }
public string NormalizedName { get; set; }
}
}

View File

@ -1,33 +1,28 @@
using System; using System;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using MapTo;
namespace BlueWest.WebApi.Context.Users; namespace BlueWest.WebApi.Context.Users
/// <inheritdoc />
public class ApplicationRoleClaim : IdentityRoleClaim<string>
{ {
public sealed override int Id { get; set; }
#region ApplicationRole
public sealed override string RoleId { get; set; }
public ApplicationRole ApplicationRole { get; set; }
#endregion
public sealed override string ClaimType { get; set; }
public sealed override string ClaimValue { get; set; }
public ApplicationRoleClaim() { }
public ApplicationRoleClaim(ApplicationRoleClaim applicationRoleClaim)
{
Id = applicationRoleClaim.Id;
RoleId = applicationRoleClaim.RoleId;
ApplicationRole = applicationRoleClaim.ApplicationRole;
ClaimType = applicationRoleClaim.ClaimType;
ClaimValue = applicationRoleClaim.ClaimValue;
}
} /// <inheritdoc />
[MapFrom(typeof(ApplicationRoleClaimUnique))]
public partial class ApplicationRoleClaim : IdentityRoleClaim<string>
{
public sealed override int Id { get; set; }
#region ApplicationRole
public sealed override string RoleId { get; set; }
public ApplicationRole ApplicationRole { get; set; }
#endregion
public sealed override string ClaimType { get; set; }
public sealed override string ClaimValue { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using MapTo;
namespace BlueWest.WebApi.Context.Users
{
[MapFrom(typeof(ApplicationRoleClaim))]
public partial class ApplicationRoleClaimUnique
{
public int Id { get; set; }
public string RoleId { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
}
}

View File

@ -3,38 +3,32 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using BlueWest.Data; using BlueWest.Data;
using MapTo;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace BlueWest.WebApi.Context.Users; namespace BlueWest.WebApi.Context.Users
/// <summary>
/// Application User in the Identity System.
/// </summary>
public class ApplicationUser : IdentityUser<string>
{ {
/// <summary>
/// Application User in the Identity System.
/// </summary>
[MapFrom(typeof(ApplicationUserUnique))]
[UseUpdate]
public partial class ApplicationUser : IdentityUser<string>
{
/// <summary> /// <summary>
/// Gets or sets the primary key for this user. /// Gets or sets the primary key for this user.
/// </summary> /// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[PersonalData] [PersonalData]
public new string Id { get; set; } public new string Id { get; set; }
public List<User> Users { get; set; } public List<User> Users { get; set; }
/// <summary>
/// Gets or sets the user name for this user.
/// </summary>
[ProtectedPersonalData] [ProtectedPersonalData]
public override string UserName { get; set; } public override string UserName { get; set; }
/// <summary>
/// Gets or sets the normalized user name for this user.
/// </summary>
public override string NormalizedUserName { get; set; } public override string NormalizedUserName { get; set; }
/// <summary>
/// Gets or sets the email address for this user.
/// </summary>
[ProtectedPersonalData] [ProtectedPersonalData]
public override string Email { get; set; } public override string Email { get; set; }
@ -103,5 +97,5 @@ public class ApplicationUser : IdentityUser<string>
/// Gets or sets the number of failed login attempts for the current user. /// Gets or sets the number of failed login attempts for the current user.
/// </summary> /// </summary>
public override int AccessFailedCount { get; set; } public override int AccessFailedCount { get; set; }
}
} }

View File

@ -0,0 +1,25 @@
using System;
using MapTo;
namespace BlueWest.WebApi.Context.Users
{
[MapFrom(typeof(ApplicationUser))]
public partial class ApplicationUserUnique
{
public string Id { get; set; }
public string UserName { get; set; }
public string NormalizedUserName { get; set; }
public string Email { get; set; }
public string NormalizedEmail { get; set; }
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string ConcurrencyStamp { get; set; }
}
}

View File

@ -1,40 +1,32 @@
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using MapTo;
namespace BlueWest.WebApi.Context.Users; namespace BlueWest.WebApi.Context.Users
/// <inheritdoc />
public class ApplicationUserClaim : IdentityUserClaim<string>
{ {
/// <inheritdoc /> [MapFrom(typeof(ApplicationUserClaimUnique))]
public sealed override int Id { get; set; }
#region User
/// <inheritdoc />
public sealed override string UserId { get; set; }
/// <summary>
/// Application User entity
/// </summary>
public ApplicationUser ApplicationUser { get; set; }
#endregion
/// <inheritdoc />
public sealed override string ClaimType { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public sealed override string ClaimValue { get; set; } public partial class ApplicationUserClaim : IdentityUserClaim<string>
public ApplicationUserClaim(ApplicationUserClaim applicationUserClaim)
{ {
Id = applicationUserClaim.Id; /// <inheritdoc />
UserId = applicationUserClaim.UserId; public sealed override int Id { get; set; }
ApplicationUser = applicationUserClaim.ApplicationUser;
ClaimType = applicationUserClaim.ClaimType; #region User
ClaimValue = applicationUserClaim.ClaimValue; /// <inheritdoc />
} public sealed override string UserId { get; set; }
/// <summary>
/// Application User entity
/// </summary>
public ApplicationUser ApplicationUser { get; set; }
#endregion
/// <inheritdoc />
public sealed override string ClaimType { get; set; }
/// <inheritdoc />
public sealed override string ClaimValue { get; set; }
public ApplicationUserClaim()
{
} }
} }

View File

@ -0,0 +1,14 @@
using MapTo;
namespace BlueWest.WebApi.Context.Users
{
[MapFrom(typeof(ApplicationUserClaim))]
public partial class ApplicationUserClaimUnique
{
public int Id { get; set; }
public string UserId { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
}
}

View File

@ -1,33 +1,28 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using MapTo;
namespace BlueWest.WebApi.Context.Users; namespace BlueWest.WebApi.Context.Users
/// <inheritdoc />
public class ApplicationUserRole : IdentityUserRole<string>
{ {
/// <summary>
/// User entity of this role
/// </summary>
public ApplicationUser User { get; set; }
public ApplicationRole ApplicationRole { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public sealed override string UserId { get; set; } [MapFrom(typeof(ApplicationUserRoleUnique))]
/// <inheritdoc /> public partial class ApplicationUserRole : IdentityUserRole<string>
public sealed override string RoleId { get; set; }
public ApplicationUserRole() { }
public ApplicationUserRole(ApplicationUserRole applicationUserRole)
{ {
User = applicationUserRole.User; /// <summary>
UserId = applicationUserRole.UserId; /// User entity of this role
RoleId = applicationUserRole.RoleId; /// </summary>
ApplicationRole = applicationUserRole.ApplicationRole; public ApplicationUser User { get; set; }
public ApplicationRole ApplicationRole { get; set; }
/// <inheritdoc />
public sealed override string UserId { get; set; }
/// <inheritdoc />
public sealed override string RoleId { get; set; }
} }
} }

View File

@ -0,0 +1,13 @@
using MapTo;
namespace BlueWest.WebApi.Context.Users
{
[MapFrom(typeof(ApplicationUserRole))]
public partial class ApplicationUserRoleUnique
{
public string UserId { get; set; }
public string RoleId { get; set; }
}
}

View File

@ -22,7 +22,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Application" />
<Folder Include="Capital" /> <Folder Include="Capital" />
</ItemGroup> </ItemGroup>
<Import Project="..\include\BlueWest.MapTo\src\BlueWest.MapTo\MapTo.props" /> <Import Project="..\include\BlueWest.MapTo\src\BlueWest.MapTo\MapTo.props" />