This commit is contained in:
parent
2a404c3560
commit
5c32055f6a
|
@ -1,4 +1,5 @@
|
|||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.Context.Users;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BlueWest.WebApi.EF.Model
|
||||
|
@ -24,6 +25,7 @@ namespace BlueWest.WebApi.EF.Model
|
|||
.ConfigureDatabaseKeys()
|
||||
.CurrencyModel()
|
||||
.ConfigureUserModel();
|
||||
//.ConfigureIdentityModel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -123,6 +125,40 @@ namespace BlueWest.WebApi.EF.Model
|
|||
|
||||
#endregion
|
||||
|
||||
public static void ConfigureIdentityModel(this ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<ApplicationUser>(b =>
|
||||
{
|
||||
b.HasMany<ApplicationUserRole>().WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationRole>(b =>
|
||||
{
|
||||
b.HasKey(r => r.Id);
|
||||
b.HasIndex(r => r.NormalizedName).HasDatabaseName("RoleNameIndex").IsUnique();
|
||||
b.ToTable("Roles");
|
||||
b.Property(r => r.ConcurrencyStamp).IsConcurrencyToken();
|
||||
|
||||
b.Property(u => u.Name).HasMaxLength(256);
|
||||
b.Property(u => u.NormalizedName).HasMaxLength(256);
|
||||
|
||||
b.HasMany<ApplicationUserRole>().WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
|
||||
b.HasMany<ApplicationRoleClaim>().WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationRoleClaim>(b =>
|
||||
{
|
||||
b.HasKey(rc => rc.Id);
|
||||
b.ToTable("RoleClaims");
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationUserRole>(b =>
|
||||
{
|
||||
b.HasKey(r => new { r.UserId, r.RoleId });
|
||||
b.ToTable("UserRoles");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,25 +8,18 @@
|
|||
/// <param name="where">Optional where predicate.</param>
|
||||
/// <param name="orderBy">Optional order by predicate.</param>
|
||||
/// <returns>A bool if the result is successful and a projection of the first occurrence of {propertyName}. </returns>
|
||||
public static (bool, {returnTypeFullName}[]) Get{propertyName}(this {contextFullName} dbContext, int skip = 0, int take = 50, int orderDir = 1,
|
||||
Expression <Func<{returnTypeFullName}, bool> > where = null,
|
||||
Expression <Func<{returnTypeFullName}, object> > orderBy = null)
|
||||
public static (bool, System.Collections.Generic.List<{returnTypeFullName}>) Get{propertyName}(this {contextFullName} dbContext, int skip = 0, int take = 50, int orderDir = 1)
|
||||
{
|
||||
if (take > 200) take = 200;
|
||||
|
||||
var query = dbContext
|
||||
.{propertyName}
|
||||
.Select(x => new {returnTypeFullName}(x))
|
||||
.Skip(skip)
|
||||
.Take(take);
|
||||
.Take(take)
|
||||
.Select(x => new {returnTypeFullName}(x));
|
||||
|
||||
if (where != null) query = query.Where(where);
|
||||
|
||||
if(orderBy != null)
|
||||
{
|
||||
if (orderDir == 1) query = query.OrderBy(orderBy);
|
||||
else query = query.OrderByDescending(orderBy);
|
||||
}
|
||||
|
||||
return (query.Any(), query.ToArray());
|
||||
var result = query.ToList();
|
||||
|
||||
return (result.Any(), result);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
using BlueWest.WebApi.Context.Users;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
|
@ -11,24 +10,36 @@ using Microsoft.AspNetCore.Mvc;
|
|||
|
||||
namespace BlueWest.WebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Auth controller
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
|
||||
[ApiController]
|
||||
public class AuthController : Controller
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IAuthManager _authManager;
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
public AuthController( IMapper mapper, IAuthManager authManager, IUserManager userManager)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="authManager"></param>
|
||||
/// <param name="userManager"></param>
|
||||
public AuthController( IAuthManager authManager, IUserManager userManager)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_authManager = authManager;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Signup user
|
||||
/// </summary>
|
||||
/// <param name="registerViewModel"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("register")]
|
||||
public async Task<ActionResult<IdentityResult>> SignupUserAsync(RegisterViewModel registerViewModel)
|
||||
|
@ -45,7 +56,7 @@ namespace BlueWest.WebApi.Controllers;
|
|||
|
||||
if (loginResultSucceded != null)
|
||||
{
|
||||
return Ok(_mapper.Map<AccessToken>(loginResultSucceded));
|
||||
return Ok(loginResultSucceded);
|
||||
|
||||
}
|
||||
return Problem();
|
||||
|
@ -58,7 +69,6 @@ namespace BlueWest.WebApi.Controllers;
|
|||
{
|
||||
var user = await _userManager.FindByEmailAsync(loginDto.Email);
|
||||
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
if(await _userManager.CheckPasswordAsync(user, loginDto.Password))
|
||||
|
@ -78,8 +88,6 @@ namespace BlueWest.WebApi.Controllers;
|
|||
public async Task<ActionResult<IdentityResult>> DoLogoutAsync(LoginViewModel loginDto)
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
|
||||
return Json(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.EF;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -14,6 +17,8 @@ namespace BlueWest.WebApi.Controllers
|
|||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
|
||||
public class CountryController : ControllerBase
|
||||
{
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.EF;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -13,6 +16,8 @@ namespace BlueWest.WebApi.Controllers
|
|||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
|
||||
public partial class CurrencyController : ControllerBase
|
||||
{
|
||||
|
||||
|
@ -40,7 +45,7 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpGet]
|
||||
public ActionResult GetCurrencies(int skip = 0, int take = 50, int orderDir = 1)
|
||||
{
|
||||
var (success, result) = _dbContext.GetCurrencies(skip, take, orderDir, null, x => x.Id);
|
||||
var (success, result) = _dbContext.GetCurrencies(skip, take, orderDir);
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.EF;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -11,6 +14,8 @@ namespace BlueWest.WebApi.Controllers;
|
|||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
|
||||
public class FinanceController : ControllerBase
|
||||
{
|
||||
private readonly FinanceDbContext _dbContext;
|
||||
|
|
|
@ -4,6 +4,9 @@ using System.Collections.Immutable;
|
|||
using System.Linq;
|
||||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.EF;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -14,6 +17,8 @@ namespace BlueWest.WebApi.Controllers
|
|||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
|
||||
|
|
|
@ -71,40 +71,42 @@ namespace BlueWest.WebApi
|
|||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
options.IncludeXmlComments(xmlPath);
|
||||
});
|
||||
|
||||
|
||||
services.Configure<IdentityOptions>(options =>
|
||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
// Password settings.
|
||||
options.Password.RequireDigit = true;
|
||||
options.Password.RequireLowercase = true;
|
||||
options.Password.RequireNonAlphanumeric = true;
|
||||
options.Password.RequireUppercase = true;
|
||||
options.Password.RequiredLength = 6;
|
||||
options.Password.RequiredUniqueChars = 1;
|
||||
|
||||
// Lockout settings.
|
||||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
||||
options.Lockout.MaxFailedAccessAttempts = 5;
|
||||
options.Lockout.AllowedForNewUsers = true;
|
||||
|
||||
// User settings.
|
||||
options.User.AllowedUserNameCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
|
||||
options.User.RequireUniqueEmail = false;
|
||||
Description =
|
||||
"JWT Authorization header using the Bearer scheme (Example: 'Bearer 12345abcdef')",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Scheme = "Bearer"
|
||||
});
|
||||
|
||||
services.AddScoped<SignInManager>();
|
||||
|
||||
services.AddScoped<RoleManager>();
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
}
|
||||
},
|
||||
Array.Empty<string>()
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
services.AddSingleton<IFileProvider>(
|
||||
new PhysicalFileProvider(
|
||||
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/ImageFiles")
|
||||
)
|
||||
);
|
||||
*/
|
||||
|
||||
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("config.json")
|
||||
|
@ -115,6 +117,7 @@ namespace BlueWest.WebApi
|
|||
services
|
||||
.AddSingleton<EventManager>();
|
||||
|
||||
|
||||
switch (allowedDatabase)
|
||||
{
|
||||
case "mysql":
|
||||
|
@ -129,6 +132,9 @@ namespace BlueWest.WebApi
|
|||
throw new InvalidOperationException("config.json doesn't specify a valid database. Use mysql or sqlite.");
|
||||
}
|
||||
|
||||
services.AddAuthServerServices(MyAllowSpecificOrigins, _configuration, _environment);
|
||||
|
||||
|
||||
services.AddScoped<ExchangeInterface>();
|
||||
|
||||
|
||||
|
@ -154,9 +160,11 @@ namespace BlueWest.WebApi
|
|||
c.RoutePrefix = "swagger";
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "BlueWest.Api v1");
|
||||
});
|
||||
app.UseStaticFiles();
|
||||
//app.UseStaticFiles();
|
||||
//app.UseHttpsRedirection();
|
||||
|
||||
|
||||
|
||||
app.UseRouting();
|
||||
app.UseCors(MyAllowSpecificOrigins);
|
||||
app.UseAuthentication();
|
||||
|
|
|
@ -79,7 +79,8 @@ namespace BlueWest.WebApi
|
|||
.AddDbContextPool<UserDbContext>(options => options.GetMySqlSettings(configuration, environment))
|
||||
.AddDbContextPool<CountryDbContext>(options => options.GetMySqlSettings(configuration, environment))
|
||||
.AddDbContextPool<FinanceDbContext>(options => options.GetMySqlSettings(configuration, environment))
|
||||
.AddDbContextPool<CompanyDbContext>(options => options.GetMySqlSettings(configuration, environment));
|
||||
.AddDbContextPool<CompanyDbContext>(options => options.GetMySqlSettings(configuration, environment))
|
||||
.AddDbContextPool<ApplicationUserDbContext>(options => options.GetMySqlSettings(configuration, environment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -99,39 +100,41 @@ namespace BlueWest.WebApi
|
|||
.AddDbContextPool<CountryDbContext>(options => options.UseSqlite(sqliteConString))
|
||||
.AddDbContextPool<FinanceDbContext>(options => options.UseSqlite(sqliteConString))
|
||||
.AddDbContextPool<CompanyDbContext>(options => options.UseSqlite(sqliteConString));
|
||||
|
||||
}
|
||||
|
||||
public static void AddAuthServerServices(this IServiceCollection services, string origins, IConfiguration _configuration)
|
||||
public static IServiceCollection AddAuthServerServices(this IServiceCollection services, string origins, IConfiguration configuration , IWebHostEnvironment environment)
|
||||
{
|
||||
var sqliteConString = "Data Source=BlueWest.Api.db";
|
||||
|
||||
services.AddDbContext<ApplicationUserDbContext>(options => options.UseSqlite(sqliteConString));
|
||||
|
||||
services.AddScoped<IJwtTokenHandler, JwtTokenHandler>();
|
||||
services.AddScoped<IJwtFactory, JwtFactory>();
|
||||
|
||||
// User management
|
||||
|
||||
services
|
||||
.AddScoped<UserRepository>()
|
||||
.AddScoped<IUserManager, UserManager>()
|
||||
.AddScoped<IAuthManager, AuthManager>()
|
||||
.AddScoped<IHasher, Hasher>();
|
||||
|
||||
services
|
||||
.AddIdentityCore<ApplicationUser>(opt => { opt.User.RequireUniqueEmail = true; })
|
||||
.AddEntityFrameworkStores<UserDbContext>()
|
||||
.AddUserManager<UserManager>()
|
||||
.AddUserStore<UserRepository>();
|
||||
// Database Context and Swagger
|
||||
|
||||
services.TryAddSingleton<ISystemClock, SystemClock>();
|
||||
// Registering 'services' and Authentication, Cookies, JWT
|
||||
services
|
||||
.AddScoped<IUsersRepo, UserRepository>()
|
||||
.AddScoped<IUserManager, UserManager>() // So it gets successfully registered in UserManager
|
||||
.AddScoped<IAuthManager, AuthManager>()
|
||||
.AddScoped<IHasher, Hasher>();
|
||||
|
||||
|
||||
// Register the ConfigurationBuilder instance of AuthSettings
|
||||
var authSettings = _configuration.GetSection(nameof(AuthSettings));
|
||||
var authSettings = configuration.GetSection(nameof(AuthSettings));
|
||||
services.Configure<AuthSettings>(authSettings);
|
||||
var signingKey = new SymmetricSecurityKey
|
||||
(Encoding.ASCII.GetBytes(authSettings[nameof(AuthSettings.SecretKey)]));
|
||||
|
||||
// jwt wire up
|
||||
// Get options from app settings
|
||||
var jwtAppSettingOptions = _configuration
|
||||
var jwtAppSettingOptions = configuration
|
||||
.GetSection(nameof(JwtIssuerOptions));
|
||||
|
||||
// Configure JwtIssuerOptions
|
||||
|
@ -169,7 +172,7 @@ namespace BlueWest.WebApi
|
|||
})
|
||||
.AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/api/auth/login2";
|
||||
options.LoginPath = "/api/auth/login";
|
||||
options.LogoutPath = "/api/auth/logout";
|
||||
})
|
||||
.AddJwtBearer(configureOptions =>
|
||||
|
@ -202,7 +205,7 @@ namespace BlueWest.WebApi
|
|||
});
|
||||
|
||||
// add identity
|
||||
var identityBuilder = services.AddIdentityCore<User>(o =>
|
||||
var identityBuilder = services.AddIdentityCore<ApplicationUser>(o =>
|
||||
{
|
||||
// configure identity options
|
||||
o.Password.RequireDigit = false;
|
||||
|
@ -212,28 +215,14 @@ namespace BlueWest.WebApi
|
|||
o.Password.RequiredLength = 6;
|
||||
});
|
||||
|
||||
identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(IdentityRole), identityBuilder.Services);
|
||||
identityBuilder.AddEntityFrameworkStores<UserDbContext>().AddDefaultTokenProviders();
|
||||
}
|
||||
public static void ConfigureApiWithUsers(this IApplicationBuilder app, IWebHostEnvironment env, string origins)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseHsts();
|
||||
identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(ApplicationRole), identityBuilder.Services);
|
||||
identityBuilder
|
||||
.AddEntityFrameworkStores<ApplicationUserDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUI(config => { config.SwaggerEndpoint("/swagger/v1/swagger.json", "Commands And Snippets API"); })
|
||||
.UseRouting()
|
||||
.UseAuthentication()
|
||||
.UseAuthorization()
|
||||
.UseCors(origins)
|
||||
.UseEndpoints(endpoints => endpoints.MapControllers());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
dotnet ef database update -c ApplicationUserDbContext
|
||||
dotnet ef database update -c CountryDbContext
|
||||
dotnet ef database update -c CompanyDbContext
|
||||
dotnet ef database update -c UserDbContext
|
||||
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace BlueWest.WebApi.Context.Users;
|
||||
|
@ -12,8 +14,9 @@ public class ApplicationUser : IdentityUser<string>
|
|||
/// <summary>
|
||||
/// Gets or sets the primary key for this user.
|
||||
/// </summary>
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[PersonalData]
|
||||
public new Guid Id { get; set; }
|
||||
public new string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user name for this user.
|
||||
|
|
|
@ -22,22 +22,8 @@ public class ApplicationUserDbContext : IdentityDbContext<
|
|||
ApplicationUserRole,
|
||||
ApplicationUserLogin,
|
||||
ApplicationRoleClaim,
|
||||
ApplicationUserToken>, IPersistedGrantDbContext
|
||||
ApplicationUserToken>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User roles.
|
||||
/// </summary>
|
||||
public override DbSet<ApplicationUserRole> UserRoles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of roles.
|
||||
/// </summary>
|
||||
public override DbSet<ApplicationRole> Roles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of role claims.
|
||||
/// </summary>
|
||||
public override DbSet<ApplicationRoleClaim> RoleClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configures the schema needed for the identity framework.
|
||||
|
@ -50,9 +36,10 @@ public class ApplicationUserDbContext : IdentityDbContext<
|
|||
/// Database for the context of database users
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public ApplicationUserDbContext(DbContextOptions<UserDbContext> options) : base(options)
|
||||
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options) : base(options)
|
||||
{
|
||||
Database.EnsureCreated();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -64,13 +51,19 @@ public class ApplicationUserDbContext : IdentityDbContext<
|
|||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
builder.ConfigureCurrentDbModel();
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder.Entity<ApplicationUser>(b =>
|
||||
{
|
||||
b.HasMany<ApplicationUserRole>().WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
|
||||
b.HasMany<ApplicationUserRole>()
|
||||
.WithOne()
|
||||
.HasForeignKey(ur => ur.UserId).IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationUser>().ToTable("ApplicationUser")
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
|
||||
|
||||
builder.Entity<ApplicationRole>(b =>
|
||||
{
|
||||
b.HasKey(r => r.Id);
|
||||
|
@ -96,14 +89,8 @@ public class ApplicationUserDbContext : IdentityDbContext<
|
|||
b.HasKey(r => new { r.UserId, r.RoleId });
|
||||
b.ToTable("UserRoles");
|
||||
});
|
||||
|
||||
builder.ConfigureCurrentDbModel();
|
||||
}
|
||||
|
||||
public Task<int> SaveChangesAsync()
|
||||
{
|
||||
return SaveChangesAsync();
|
||||
}
|
||||
|
||||
public DbSet<PersistedGrant> PersistedGrants { get; set; }
|
||||
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
|
||||
public DbSet<Key> Keys { get; set; }
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
using BlueWest.Cryptography;
|
||||
using BlueWest.Data;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
@ -10,21 +9,26 @@ namespace BlueWest.WebApi.Context.Users;
|
|||
public class AuthManager : IAuthManager
|
||||
{
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUsersRepo _usersRepo;
|
||||
private readonly UserRepository _usersRepo;
|
||||
private readonly IHasher _hasher;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IJwtFactory _jwtFactory;
|
||||
|
||||
public AuthManager(IUserManager userManager, IHasher hasher, IMapper mapper
|
||||
, IUsersRepo usersRepo, IJwtFactory jwtFactory)
|
||||
/// <summary>
|
||||
/// Auth manager constructor
|
||||
/// </summary>
|
||||
/// <param name="userManager"></param>
|
||||
/// <param name="hasher"></param>
|
||||
/// <param name="usersRepo"></param>
|
||||
/// <param name="jwtFactory"></param>
|
||||
public AuthManager(IUserManager userManager, IHasher hasher, UserRepository usersRepo, IJwtFactory jwtFactory)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_hasher = hasher;
|
||||
_mapper = mapper;
|
||||
_usersRepo = usersRepo;
|
||||
_jwtFactory = jwtFactory;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<AccessToken> GetToken(LoginViewModel loginViewModel)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(loginViewModel.Email) && !string.IsNullOrEmpty(loginViewModel.Password))
|
||||
|
@ -48,6 +52,7 @@ public class AuthManager : IAuthManager
|
|||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> VerifyLoginAsync(string email, string password)
|
||||
{
|
||||
var user = await _userManager.FindByEmailAsync(email);
|
||||
|
@ -74,7 +79,8 @@ public class AuthManager : IAuthManager
|
|||
|
||||
public async Task<IdentityResult> CreateUserAsync(RegisterViewModel userSignupDto)
|
||||
{
|
||||
RegisterViewModel userToCreate = FromSignupToUser(userSignupDto);
|
||||
return await _userManager.CreateAsync(userToCreate.ToUser());
|
||||
}
|
||||
|
||||
return await _userManager.CreateAsync(userSignupDto.ToUser());
|
||||
}
|
||||
}
|
|
@ -4,12 +4,31 @@ using Microsoft.AspNetCore.Identity;
|
|||
|
||||
namespace BlueWest.WebApi.Context.Users;
|
||||
|
||||
/// <summary>
|
||||
/// Auth manager contract interface.
|
||||
/// </summary>
|
||||
public interface IAuthManager
|
||||
{
|
||||
/// <summary>
|
||||
/// CreateUserAsync
|
||||
/// </summary>
|
||||
/// <param name="registerViewModel"></param>
|
||||
/// <returns></returns>
|
||||
Task<IdentityResult> CreateUserAsync(RegisterViewModel registerViewModel);
|
||||
|
||||
/// <summary>
|
||||
/// VerifyLoginAsync
|
||||
/// </summary>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> VerifyLoginAsync(string email, string password);
|
||||
|
||||
/// <summary>
|
||||
/// GetToken
|
||||
/// </summary>
|
||||
/// <param name="loginViewModel"></param>
|
||||
/// <returns></returns>
|
||||
Task<AccessToken> GetToken(LoginViewModel loginViewModel);
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BlueWest.Data;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace BlueWest.WebApi.Context.Users;
|
||||
/// <summary>
|
||||
/// This is our Users repository.
|
||||
/// Since this is a simple app we'll have the following roles
|
||||
/// Admin and APIClient
|
||||
/// </summary>
|
||||
public interface IUsersRepo : IUserStore<ApplicationUser>
|
||||
{
|
||||
public Task<IEnumerable<ApplicationUser>> GetUsers();
|
||||
public Task CreateUser(ApplicationUser user);
|
||||
public Task SaveChanges();
|
||||
|
||||
public Task<ApplicationUser> GetUserById(string id);
|
||||
|
||||
Task<ApplicationUser> FindByEmailAsync(string email, CancellationToken cancellationToken);
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ public class RegisterViewModel
|
|||
[DataType(DataType.Password)]
|
||||
[Display(Name = "Password")]
|
||||
public string Password { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ConfirmPassword
|
||||
|
@ -37,6 +38,7 @@ public class RegisterViewModel
|
|||
var newUser = new ApplicationUser();
|
||||
newUser.Email = Email;
|
||||
newUser.PasswordHash = Password;
|
||||
newUser.UserName = Username;
|
||||
return newUser;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BlueWest.Cryptography;
|
||||
using BlueWest.Data;
|
||||
|
@ -12,8 +13,8 @@ namespace BlueWest.WebApi.Context.Users;
|
|||
public class UserManager : UserManager<ApplicationUser>, IUserManager
|
||||
{
|
||||
private readonly IHasher _hasher;
|
||||
private readonly IUsersRepo _usersRepo;
|
||||
public UserManager(IUsersRepo store, IOptions<IdentityOptions> optionsAccessor,
|
||||
private readonly UserRepository _usersRepo;
|
||||
public UserManager(UserRepository store, IOptions<IdentityOptions> optionsAccessor,
|
||||
IHasher passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators,
|
||||
IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer,
|
||||
IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger) : base(store,
|
||||
|
@ -24,24 +25,6 @@ public class UserManager : UserManager<ApplicationUser>, IUserManager
|
|||
_usersRepo = store;
|
||||
}
|
||||
|
||||
public override async Task<IdentityResult> CreateAsync(ApplicationUser user)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
var result = await ValidateUserAsync(user);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (Options.Lockout.AllowedForNewUsers && SupportsUserLockout)
|
||||
{
|
||||
// await GetUserLockoutStore().SetLockoutEnabledAsync(user, true, CancellationToken);
|
||||
}
|
||||
await UpdateNormalizedUserNameAsync(user);
|
||||
await UpdateNormalizedEmailAsync(user);
|
||||
|
||||
return await _usersRepo.CreateAsync(user, CancellationToken);
|
||||
}
|
||||
|
||||
public override async Task<bool> CheckPasswordAsync(ApplicationUser user, string password)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
@ -80,27 +63,6 @@ public class UserManager : UserManager<ApplicationUser>, IUserManager
|
|||
return PasswordHasher.VerifyHashedPassword(user, existingHash, password);
|
||||
}
|
||||
|
||||
public override async Task<ApplicationUser> FindByNameAsync(string userName)
|
||||
{
|
||||
if (userName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(userName));
|
||||
}
|
||||
|
||||
ApplicationUser user;
|
||||
|
||||
if (Store is IUsersRepo repo)
|
||||
{
|
||||
user = await repo.FindByNameAsync(userName, CancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
userName = NormalizeName(userName);
|
||||
user = await Store.FindByNameAsync(userName, CancellationToken);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
public override async Task<IdentityResult> ChangePasswordAsync(ApplicationUser user, string currentPassword, string newPassword)
|
||||
|
@ -137,19 +99,4 @@ public class UserManager : UserManager<ApplicationUser>, IUserManager
|
|||
return null;
|
||||
}
|
||||
|
||||
public override async Task<ApplicationUser> FindByEmailAsync(string email)
|
||||
{
|
||||
ApplicationUser user = null;
|
||||
|
||||
if (Store is IUsersRepo repo)
|
||||
{
|
||||
user = await repo.FindByEmailAsync(email, CancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
user = await Store.FindByNameAsync(email, CancellationToken);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -12,7 +13,7 @@ namespace BlueWest.WebApi.Context.Users;
|
|||
/// <summary>
|
||||
/// Users Repository
|
||||
/// </summary>
|
||||
public class UserRepository : UserStore<ApplicationUser, ApplicationRole, ApplicationUserDbContext>, IUsersRepo
|
||||
public class UserRepository : UserStore<ApplicationUser, ApplicationRole, ApplicationUserDbContext>
|
||||
{
|
||||
private readonly ApplicationUserDbContext _context;
|
||||
|
||||
|
@ -35,34 +36,48 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
/// Create Application User
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
public async Task CreateUser(ApplicationUser user)
|
||||
/*public override async Task<IdentityResult> CreateAsync(ApplicationUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
await CreateAsync(user, CancellationToken.None);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
await _context.AddAsync(user, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
return IdentityResult.Success;
|
||||
}*/
|
||||
/// <summary>
|
||||
/// Save Changes
|
||||
/// </summary>
|
||||
/*
|
||||
public async Task SaveChanges()
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private async Task<bool> SaveChanges(ApplicationUser user)
|
||||
{
|
||||
_context.Users.Update(user);
|
||||
return await _context.SaveChangesAsync() > 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispose repository
|
||||
/// </summary>
|
||||
/*
|
||||
public void Dispose()
|
||||
{
|
||||
_context.Dispose();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
/// <inheritdoc />
|
||||
public override Task<string> GetUserIdAsync(ApplicationUser user, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -85,8 +100,10 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
|
||||
return Task.FromResult(user.UserName);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <inheritdoc />
|
||||
/*
|
||||
public override async Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken)
|
||||
{
|
||||
var foundUser = await _context.Users.FirstOrDefaultAsync(x => x.Id == user.Id, cancellationToken: cancellationToken);
|
||||
|
@ -94,7 +111,9 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
foundUser.UserName = userName;
|
||||
await SaveChanges(user);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
/// <inheritdoc />
|
||||
public override Task<string> GetNormalizedUserNameAsync(ApplicationUser user, CancellationToken cancellationToken)
|
||||
{
|
||||
|
@ -107,19 +126,6 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<IdentityResult> CreateAsync(ApplicationUser user, CancellationToken cancellationToken)
|
||||
{
|
||||
var u = await _context.AddAsync(user, cancellationToken);
|
||||
|
||||
if(u.State == EntityState.Added)
|
||||
{
|
||||
await SaveChanges();
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
return IdentityResult.Failed();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<IdentityResult> UpdateAsync(ApplicationUser user, CancellationToken cancellationToken)
|
||||
|
@ -154,6 +160,7 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
var user = await db.FirstOrDefaultAsync(u => u.Id.ToString() == id);
|
||||
return user;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -178,6 +185,7 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
return Task.FromResult(!string.IsNullOrEmpty(user.PasswordHash));
|
||||
}
|
||||
|
||||
/*
|
||||
/// <inheritdoc />
|
||||
public override Task<string> GetEmailAsync(ApplicationUser user, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -220,6 +228,6 @@ public class UserRepository : UserStore<ApplicationUser, ApplicationRole, Applic
|
|||
}
|
||||
|
||||
return Task.FromResult(user.NormalizedEmail);
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
|
@ -9,5 +9,8 @@
|
|||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"DockerMySQL": "server=db;user=blueuser;password=dXjw127124dJ;database=bluedb;"
|
||||
},
|
||||
"AuthSettings": {
|
||||
"SecretKey": "d123d123d123fff12"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace BlueWest.Data
|
|||
|
||||
public List<Industry> Industry { get; set; }
|
||||
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace BlueWest.Data
|
|||
|
||||
public DateTime FoundingDate { get; set; }
|
||||
|
||||
public DateTime CreateTime { get; } = DateTime.Now;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
@ -33,6 +34,8 @@ namespace BlueWest.Data
|
|||
public List<Currency> Currencies { get; set; }
|
||||
public List<User> Users { get; set; }
|
||||
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MapTo;
|
||||
|
@ -18,6 +19,7 @@ namespace BlueWest.Data
|
|||
public string Alpha2Code { get; set; }
|
||||
|
||||
public string TLD { get; set; }
|
||||
public DateTime CreateTime { get; } = DateTime.Now;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MapTo;
|
||||
|
@ -16,6 +17,8 @@ namespace BlueWest.Data
|
|||
public int Num { get; set; }
|
||||
[MaxLength(3)] public string Code { get; set; }
|
||||
public List<Country> Countries { get; set; }
|
||||
|
||||
public DateTime CreateDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MapTo;
|
||||
|
@ -11,6 +12,7 @@ namespace BlueWest.Data
|
|||
public int Num { get; set; } // Primary key
|
||||
[MaxLength(3)] public string Code { get; set; }
|
||||
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MapTo;
|
||||
|
||||
|
@ -10,6 +11,9 @@ namespace BlueWest.Data
|
|||
public string IndustryName { get; set; }
|
||||
public Industry IndustryParent { get; set; }
|
||||
public List<Industry> IndustryChilds { get; set; }
|
||||
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using MapTo;
|
||||
|
||||
namespace BlueWest.Data
|
||||
|
@ -8,6 +9,9 @@ namespace BlueWest.Data
|
|||
public int Id { get; set; }
|
||||
public string IndustryName { get; set; }
|
||||
public Industry IndustryParent { get; set; }
|
||||
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace BlueWest.Data
|
|||
[UseUpdate]
|
||||
public partial class User
|
||||
{
|
||||
public string ApplicationUserId { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue