diff --git a/Projects/Config/WebApi.AuthApi.Config.json b/Projects/Config/WebApi.AuthApi.Config.json index d1ab4d3..60a1b11 100644 --- a/Projects/Config/WebApi.AuthApi.Config.json +++ b/Projects/Config/WebApi.AuthApi.Config.json @@ -18,7 +18,6 @@ "Port": 1433, "DBName": "AccountDB", "DBID": 1, - "DBContext": "AccountDB", "UserID": "SystemX", "Password": "X" }, @@ -26,8 +25,7 @@ "IP": "127.0.0.1", "Port": 1433, "DBName": "AccountDB_DEV", - "DBID": 2, - "DBContext": "AccountDB", + "DBID": 2, "UserID": "SystemX", "Password": "X" } diff --git a/Projects/Config/log4net.config b/Projects/Config/log4net.config index b970851..b7743e6 100644 --- a/Projects/Config/log4net.config +++ b/Projects/Config/log4net.config @@ -52,7 +52,7 @@ - + diff --git a/Projects/DLL/SystemX.Core.dll b/Projects/DLL/SystemX.Core.dll index 5ab830f..cf2421f 100644 Binary files a/Projects/DLL/SystemX.Core.dll and b/Projects/DLL/SystemX.Core.dll differ diff --git a/Projects/SystemX.Core/DBPatch/sqlScripts/dacpac/SystemX.DB.AccountDB.dacpac b/Projects/SystemX.Core/DBPatch/sqlScripts/dacpac/SystemX.DB.AccountDB.dacpac index 67cb16e..3dca7fa 100644 Binary files a/Projects/SystemX.Core/DBPatch/sqlScripts/dacpac/SystemX.DB.AccountDB.dacpac and b/Projects/SystemX.Core/DBPatch/sqlScripts/dacpac/SystemX.DB.AccountDB.dacpac differ diff --git a/Projects/WebApi/AuthApi/Controllers/CommonController.cs b/Projects/SystemX.Core/SystemX.Core/Controller/CommonController.cs similarity index 72% rename from Projects/WebApi/AuthApi/Controllers/CommonController.cs rename to Projects/SystemX.Core/SystemX.Core/Controller/CommonController.cs index ef12193..f51f171 100644 --- a/Projects/WebApi/AuthApi/Controllers/CommonController.cs +++ b/Projects/SystemX.Core/SystemX.Core/Controller/CommonController.cs @@ -1,16 +1,23 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Config; using SystemX.Core.Services; -using WebApi.Library.Config; -namespace AuthApi.Controllers +namespace SystemX.Core.Controller { - public class CommonController : ControllerBase + public class CommonController : ControllerBase where T : WebCommonConfig { public readonly IServiceProvider _serviceProvider; public readonly IHttpContextAccessor _httpContextAccessor; - public readonly ConfigService? _configService; + public readonly ConfigService? _configService; protected static Guid guid { get; private set; } = Guid.NewGuid(); @@ -21,9 +28,9 @@ namespace AuthApi.Controllers _httpContextAccessor = httpContextAccessor; //service - _configService = _serviceProvider.GetService>(); + _configService = _serviceProvider.GetRequiredService>(); } - + /// /// Request 클라이언트 IP /// @@ -53,7 +60,7 @@ namespace AuthApi.Controllers /// protected virtual string GetMethodName([CallerMemberName] string callerMemberName = "") { - return callerMemberName; + return $"{callerMemberName}()"; } } } diff --git a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Context/AccountDbContext.cs b/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Context/AccountDbContext.cs deleted file mode 100644 index f330eda..0000000 --- a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Context/AccountDbContext.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore; -using SystemX.Core.DB.DBContext.AccountDB.Tables; - -namespace SystemX.Core.DB.DBContext.AccountDB.Context; - -public partial class AccountDbContext : DbContext -{ - public AccountDbContext() - { - } - - public AccountDbContext(DbContextOptions options) - : base(options) - { - } - - public virtual DbSet TRefreshTokens { get; set; } - - public virtual DbSet TRoles { get; set; } - - public virtual DbSet TUsers { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) -#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. - => optionsBuilder.UseSqlServer("server=127.0.0.1; user id=SystemX; password=X; database=AccountDB; TrustServerCertificate=true;"); - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.CAuid).HasName("PK__tRefresh__FBF0855465EB95AB"); - - entity.ToTable("tRefreshToken"); - - entity.Property(e => e.CAuid) - .HasMaxLength(250) - .HasColumnName("cAuid"); - entity.Property(e => e.CRefreshToken) - .HasMaxLength(1000) - .HasColumnName("cRefreshToken"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.CAuid).HasName("PK__tRole__FBF085540BB887D7"); - - entity.ToTable("tRole"); - - entity.Property(e => e.CAuid) - .HasMaxLength(250) - .HasColumnName("cAuid"); - entity.Property(e => e.CRoleId).HasColumnName("cRoleID"); - entity.Property(e => e.CRoleName) - .HasMaxLength(20) - .HasColumnName("cRoleName"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.CUserId).HasName("PK__tUser__A75DC19A721265FF"); - - entity.ToTable("tUser"); - - entity.Property(e => e.CUserId) - .HasMaxLength(50) - .HasColumnName("cUserID"); - entity.Property(e => e.CAuid) - .HasMaxLength(250) - .HasColumnName("cAuid"); - entity.Property(e => e.CCreateDateTime).HasColumnName("cCreateDateTime"); - entity.Property(e => e.CLastLoginDateTime).HasColumnName("cLastLoginDateTime"); - entity.Property(e => e.CPasswordHashed) - .HasMaxLength(250) - .HasColumnName("cPasswordHashed"); - entity.Property(e => e.CState).HasColumnName("cState"); - }); - - OnModelCreatingPartial(modelBuilder); - } - - partial void OnModelCreatingPartial(ModelBuilder modelBuilder); -} diff --git a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRefreshToken.cs b/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRefreshToken.cs deleted file mode 100644 index c2578dc..0000000 --- a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRefreshToken.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SystemX.Core.DB.DBContext.AccountDB.Tables; - -public partial class TRefreshToken -{ - public string CAuid { get; set; } = null!; - - public string CRefreshToken { get; set; } = null!; -} diff --git a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRole.cs b/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRole.cs deleted file mode 100644 index 5404196..0000000 --- a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TRole.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SystemX.Core.DB.DBContext.AccountDB.Tables; - -public partial class TRole -{ - public string CAuid { get; set; } = null!; - - public byte CRoleId { get; set; } - - public string CRoleName { get; set; } = null!; -} diff --git a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TUser.cs b/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TUser.cs deleted file mode 100644 index 4a10d36..0000000 --- a/Projects/SystemX.Core/SystemX.Core/DB/DBContext/AccountDB/Tables/TUser.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SystemX.Core.DB.DBContext.AccountDB.Tables; - -public partial class TUser -{ - public string CUserId { get; set; } = null!; - - public string CAuid { get; set; } = null!; - - public string CPasswordHashed { get; set; } = null!; - - public byte CState { get; set; } - - public DateTime CCreateDateTime { get; set; } - - public DateTime? CLastLoginDateTime { get; set; } -} diff --git a/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs b/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs index adef78f..4eb1b00 100644 --- a/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs +++ b/Projects/SystemX.Core/SystemX.Core/Log4net/Log4net.cs @@ -363,7 +363,7 @@ public static class Log4net - + diff --git a/Projects/SystemX.Core/SystemX.Core/Model/Auth/LoginModel.cs b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Login.cs similarity index 92% rename from Projects/SystemX.Core/SystemX.Core/Model/Auth/LoginModel.cs rename to Projects/SystemX.Core/SystemX.Core/Model/Auth/Login.cs index 997084b..58d60b3 100644 --- a/Projects/SystemX.Core/SystemX.Core/Model/Auth/LoginModel.cs +++ b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Login.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace SystemX.Core.Model.Auth { //로그인 요청 모델 - public class LoginModel + public class Login { [Required] public string? UserID { get; set; } @@ -19,7 +19,7 @@ namespace SystemX.Core.Model.Auth } //로그인 응답 모델 - public class LoginResponseModel + public class LoginResponse { public string? UserID { get; set; } public UserRole Role { get; set; } diff --git a/Projects/SystemX.Core/SystemX.Core/Model/Auth/LogoutModel.cs b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Logout.cs similarity index 85% rename from Projects/SystemX.Core/SystemX.Core/Model/Auth/LogoutModel.cs rename to Projects/SystemX.Core/SystemX.Core/Model/Auth/Logout.cs index bf8f7a1..85767d2 100644 --- a/Projects/SystemX.Core/SystemX.Core/Model/Auth/LogoutModel.cs +++ b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Logout.cs @@ -8,13 +8,13 @@ using System.Threading.Tasks; namespace SystemX.Core.Model.Auth { - public class LogoutModel + public class Logout { [Required] public string? UserID { get; set; } } - public class LogoutResponseModel + public class LogoutResponse { public string? UserID { get; set; } diff --git a/Projects/SystemX.Core/SystemX.Core/Model/Auth/RegisterModel.cs b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Register.cs similarity index 92% rename from Projects/SystemX.Core/SystemX.Core/Model/Auth/RegisterModel.cs rename to Projects/SystemX.Core/SystemX.Core/Model/Auth/Register.cs index 67085f8..738162c 100644 --- a/Projects/SystemX.Core/SystemX.Core/Model/Auth/RegisterModel.cs +++ b/Projects/SystemX.Core/SystemX.Core/Model/Auth/Register.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace SystemX.Core.Model.Auth { //유저 등록 모델 - public class RegisterModel + public class Register { [Required] public string UserID { get; set; } = string.Empty; @@ -24,7 +24,7 @@ namespace SystemX.Core.Model.Auth public UserRole Role { get; set; } = UserRole.User; } - public class RegisterResponseModel + public class RegisterResponse { public string? UserID { get; set; } public UserRole Role { get; set; } diff --git a/Projects/SystemX.Core/SystemX.Core/Model/Auth/UserModel.cs b/Projects/SystemX.Core/SystemX.Core/Model/Auth/UserModel.cs deleted file mode 100644 index 660f847..0000000 --- a/Projects/SystemX.Core/SystemX.Core/Model/Auth/UserModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SystemX.Core.Model.Auth -{ - public class UserModel - { - //public TUser? TUser { get; set; } - //public TRole? TRole { get; set; } - } -} diff --git a/Projects/SystemX.Core/SystemX.Core/Services/DBContextProvider.cs b/Projects/SystemX.Core/SystemX.Core/Services/DBContextProvider.cs new file mode 100644 index 0000000..0e7e12d --- /dev/null +++ b/Projects/SystemX.Core/SystemX.Core/Services/DBContextProvider.cs @@ -0,0 +1,45 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SystemX.Core.Config.Model; + +namespace SystemX.Core.Services +{ + public class DbContextProvider + { + private Dictionary DBDictionary = new Dictionary(); + + public void SetDBList(IList? DBList) + { + if (DBList?.Count > 0) + { + foreach (var db in DBList) + { + if (DBDictionary.ContainsKey($"{db.DBName}") == false) + DBDictionary.Add($"{db.DBName}", db); + else + Log4net.WriteLine($"Exist key DB Dictionary {db.DBName}", LogType.Error); + } + } + } + + // 또는 context 직접 반환 (주의: caller가 Dispose 해야 함) + public TContext? GetDBContext(string dbName) where TContext : DbContext + { + if(DBDictionary.TryGetValue(dbName, out var db) == true) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer(db.ConvertToConnectionString()); + + return (TContext)Activator.CreateInstance(typeof(TContext), optionsBuilder.Options); + } + + return null; + } + } +} diff --git a/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj b/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj index 3ffe46e..ed90dae 100644 --- a/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj +++ b/Projects/SystemX.Core/SystemX.Core/SystemX.Core.csproj @@ -20,6 +20,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Projects/SystemX.Core/SystemX.Core/Utils/DBUtils.cs b/Projects/SystemX.Core/SystemX.Core/Utils/DBUtils.cs index eecdfe7..adb4a4c 100644 --- a/Projects/SystemX.Core/SystemX.Core/Utils/DBUtils.cs +++ b/Projects/SystemX.Core/SystemX.Core/Utils/DBUtils.cs @@ -12,7 +12,7 @@ public static class DBUtils /// public static string ConvertToConnectionString(this DataBase dbConfig) { - return $"server={dbConfig.IP},{dbConfig.Port}; user id={dbConfig.UserID}; password={dbConfig.Password}; database={dbConfig.DBName};"; + return $"server={dbConfig.IP},{dbConfig.Port}; user id={dbConfig.UserID}; password={dbConfig.Password}; database={dbConfig.DBName}; TrustServerCertificate=True;"; } } diff --git a/Projects/WebApi/AuthApi/AuthApi.http b/Projects/WebApi/AuthApi/AuthApi.http deleted file mode 100644 index 63f0da0..0000000 --- a/Projects/WebApi/AuthApi/AuthApi.http +++ /dev/null @@ -1,6 +0,0 @@ -@AuthApi_HostAddress = http://localhost:5177 - -GET {{AuthApi_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/Projects/WebApi/AuthApi/Controllers/AuthController.cs b/Projects/WebApi/AuthApi/Controllers/AuthController.cs index 83c9889..7ea8a44 100644 --- a/Projects/WebApi/AuthApi/Controllers/AuthController.cs +++ b/Projects/WebApi/AuthApi/Controllers/AuthController.cs @@ -1,4 +1,5 @@ using AuthApi.Services; +using Azure.Core; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; @@ -6,15 +7,17 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using SystemX.Core; +using SystemX.Core.Controller; using SystemX.Core.Model.Auth; +using WebApi.Library.Config; namespace AuthApi.Controllers { [Tags("Auth")] [Route("api/auth")] [ApiController] - [ApiExplorerSettings(IgnoreApi = true)] - public class AuthController : CommonController + [ApiExplorerSettings(IgnoreApi = false)] + public class AuthController : CommonController { private readonly AuthService _authService; @@ -25,36 +28,39 @@ namespace AuthApi.Controllers _authService = authService; } - [HttpGet("/health")] + [HttpGet("health")] public async Task Health() { + Log4net.WriteLine($"[{GetRequestMethod()}:{GetMethodName()}] [Client IP:{GetClientIP()}] [RequestUrl:{GetRequestUrl()}]{Environment.NewLine}", LogType.CONTROLLER); await Task.CompletedTask; + return Results.Ok("Healthy"); } [HttpPost("regisger")] - public async Task Register([FromBody] RegisterModel request) + public async Task Register([FromBody] Register request) { - // Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER); + Guid guid = Guid.NewGuid(); - RegisterResponseModel response = new RegisterResponseModel(); + Log4net.WriteLine($"[Request][{GetRequestMethod()}:{GetMethodName()}][Client IP:{GetClientIP()}][RequestUrl:{GetRequestUrl()}]::({guid}){Environment.NewLine} {request.ToJson()}", LogType.CONTROLLER); + RegisterResponse response = new RegisterResponse(); if (request?.UserID != null && request?.Password != null) { response = await _authService.CreateUser(request); } - // Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER); + Log4net.WriteLine($"[Response]::({guid}){Environment.NewLine} {response.ToJson()}", LogType.CONTROLLER); return Results.Ok(response); } [HttpPost("login")] - public async Task Login([FromBody] LoginModel request) + public async Task Login([FromBody] Login request) { - // Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER); + Log4net.WriteLine($"[Request]({guid}) api/auth/register{Environment.NewLine} {request.ToJson()}", LogType.CONTROLLER); - LoginResponseModel response = new LoginResponseModel(); + LoginResponse response = new LoginResponse(); response.UserID = request.UserID; response.EC = ERROR_CODE.EC_USER_LOGIN_FAILED; @@ -75,20 +81,20 @@ namespace AuthApi.Controllers await _authService.UpdateLoginInfo(request, response.RefreshToken); } - // Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER); + Log4net.WriteLine($"[Response]({guid}) api/auth/register{Environment.NewLine} {response.ToJson()}", LogType.CONTROLLER); return Results.Ok(response); } [HttpPost("logout")] - public async Task Logout([FromBody] LogoutModel request) + public async Task Logout([FromBody] Logout request) { - // Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER); + Log4net.WriteLine($"[Request]({guid}) api/auth/register{Environment.NewLine} {request.ToJson()}", LogType.CONTROLLER); var response = _authService.LogoutUser(request); await Task.CompletedTask; - // Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER); + Log4net.WriteLine($"[Response]({guid}) api/auth/register{Environment.NewLine} {response.ToJson()}", LogType.CONTROLLER); return Results.Ok(response); } @@ -113,7 +119,7 @@ namespace AuthApi.Controllers }; } - private string GenerateJwtToken(LoginResponseModel loginResponseModel, bool isRefreshToken = false) + private string GenerateJwtToken(LoginResponse loginResponseModel, bool isRefreshToken = false) { var claims = new[] { diff --git a/Projects/WebApi/AuthApi/Program.cs b/Projects/WebApi/AuthApi/Program.cs index 5135652..cd0e835 100644 --- a/Projects/WebApi/AuthApi/Program.cs +++ b/Projects/WebApi/AuthApi/Program.cs @@ -1,10 +1,14 @@ using AuthApi.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; using Microsoft.IdentityModel.Tokens; +using System; using System.ComponentModel; using System.Text; using SystemX.Core.Services; using WebApi.Library.Config; +using WebApi.Library.DBContext.DB.DBContext.AccountDB.Context; string configDir = @"../../Config"; string configFileName = "WebApi.AuthApi.Config.json"; @@ -26,14 +30,18 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. //singleton builder.Services.AddSingleton>(); -builder.Services.AddScoped(); //scoped +builder.Services.AddScoped(); + +//db +builder.Services.AddSingleton(); // Generic builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddHttpContextAccessor(); //config preload, auth set ConfigService preloadConfig = new ConfigService(); @@ -61,7 +69,7 @@ if (preloadConfig.OpenConfig($@"{configDir}/{configFileName}") == true) ValidAudience = $"{config?.Auth?.audience}", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes($"{config?.Auth?.accessTokenSecret}")) }; - }); + }); } else { @@ -84,6 +92,24 @@ if (configService?.OpenConfig($@"{configDir}/{configFileName}") == true) { serverUrl = $"{apiConfig?.Server?.Address}:{apiConfig?.Server?.Port}"; isIIS = apiConfig!.Server.IIS; + + using(var scoped = app.Services.CreateScope()) + { + var dbProvider = scoped.ServiceProvider.GetRequiredService(); + dbProvider?.SetDBList(apiConfig?.DataBase); + } + + //dbcontext set + //app.Use(async (context, next) => + //{ + // var dbProvider = context.RequestServices.GetService(); + // // + // dbProvider?.SetDBList(apiConfig?.DataBase); + // await next.Invoke(); + //}); + + //var dbProviderService = app.Services.GetService(); + //dbProviderService?.SetDBList(apiConfig?.DataBase); } } else diff --git a/Projects/WebApi/AuthApi/Services/AuthService.cs b/Projects/WebApi/AuthApi/Services/AuthService.cs index acced8d..29583ce 100644 --- a/Projects/WebApi/AuthApi/Services/AuthService.cs +++ b/Projects/WebApi/AuthApi/Services/AuthService.cs @@ -6,8 +6,8 @@ using SystemX.Core.Config.Model; using System.Data; using SystemX.Core.DB; using Microsoft.EntityFrameworkCore; -using SystemX.Core.DB.DBContext.AccountDB.Context; -using SystemX.Core.DB.DBContext.AccountDB.Tables; +using WebApi.Library.DBContext.DB.DBContext.AccountDB.Context; +using WebApi.Library.DBContext.DB.DBContext.AccountDB.Tables; namespace AuthApi.Services { @@ -16,26 +16,22 @@ namespace AuthApi.Services private readonly IServiceProvider _serviceProvider; private readonly IServiceScopeFactory _scopeFactory; private readonly ConfigService? _configService; - - private readonly DataBase? _accountDB; - - private static List Session = new List(); + + private static List Session = new List(); public AuthService(IServiceProvider serviceProvider, IServiceScopeFactory scopeFactory, ConfigService configSerice) { _serviceProvider = serviceProvider; _configService = configSerice; _scopeFactory = scopeFactory; - _accountDB = _configService?.GetConfig()?.DataBase?.Find(x => x.DBContext == "VpkiAccountDbContext"); } /// /// create new user /// - public async Task CreateUser(RegisterModel registerModel) - { - //response - RegisterResponseModel response = new RegisterResponseModel(); + public async Task CreateUser(Register registerModel) + { + RegisterResponse response = new RegisterResponse(); response.EC = ERROR_CODE.EC_USER_REGISTER_FAILED; response.UserID = registerModel.UserID; response.Role = registerModel.Role; @@ -44,39 +40,42 @@ namespace AuthApi.Services //context using (var scope = _scopeFactory.CreateScope()) { - var context = scope.ServiceProvider.GetRequiredService(); - if (context is not null) + var provider = scope.ServiceProvider.GetRequiredService(); + using (var context = GetAccountDBContext(provider, 1)) { - var user = await context.TUsers.AsNoTracking().Where(x => x.CUserId.ToLower() == registerModel.UserID.ToLower()).ToListAsync(); - if (user?.Count <= 0) + if (context is not null) { - string auid = Guid.NewGuid().ToString(); - //user - TUser newUser = new TUser + var user = await context.TUsers.AsNoTracking().Where(x => x.CUserId.ToLower() == registerModel.UserID.ToLower()).ToListAsync(); + if (user?.Count <= 0) { - CAuid = auid, - CUserId = registerModel.UserID, - CPasswordHashed = registerModel.Password, - CCreateDateTime = DateTime.Now, - CLastLoginDateTime = new DateTime() - }; - //role - TRole newUserRole = new TRole - { - CAuid = auid, - CRoleId = Convert.ToByte(registerModel.Role), - CRoleName = registerModel.Role.ToString() - }; - - using (var transaction = await context.CreateTransactionAsync()) - { - await context.AddAsync(newUser); - await context.AddAsync(newUserRole); - - var result = await context.CloseTransactionAsync(transaction); - if (result == true) + string auid = Guid.NewGuid().ToString(); + //user + TUser newUser = new TUser { - response.EC = ERROR_CODE.EC_OK; + CAuid = auid, + CUserId = registerModel.UserID, + CPasswordHashed = registerModel.Password, + CCreateDateTime = DateTime.Now, + CLastLoginDateTime = new DateTime() + }; + //role + TRole newUserRole = new TRole + { + CAuid = auid, + CRoleId = Convert.ToByte(registerModel.Role), + CRoleName = registerModel.Role.ToString() + }; + + using (var transaction = await context.CreateTransactionAsync()) + { + await context.AddAsync(newUser); + await context.AddAsync(newUserRole); + + var result = await context.CloseTransactionAsync(transaction); + if (result == true) + { + response.EC = ERROR_CODE.EC_OK; + } } } } @@ -89,80 +88,82 @@ namespace AuthApi.Services /// /// select user(login) /// - public async Task SelectUser(LoginModel loginModel) + public async Task SelectUser(Login loginModel) { //response - LoginResponseModel response = new LoginResponseModel(); + LoginResponse response = new LoginResponse(); response.EC = ERROR_CODE.EC_USER_LOGIN_FAILED; response.UserID = loginModel.UserID; - //var session = Session.Find(x => x.UserID?.ToLower() == loginModel.UserID?.ToLower()); - //if (session?.AccessTokenExpired < DateTime.Now.ToUnixTime()) - //{ - // Session.Remove(session); - //} + var session = Session.Find(x => x.UserID?.ToLower() == loginModel.UserID?.ToLower()); + if (session?.AccessTokenExpired < DateTime.Now.ToUnixTime()) + { + Session.Remove(session); + } //기존 로그인 체크 - // if (Session.Exists(x => x.UserID == $"{loginModel.UserID?.ToLower()}") == false) + if (Session.Exists(x => x.UserID == $"{loginModel.UserID?.ToLower()}") == false) { if (loginModel != null) { //context using (var scope = _scopeFactory.CreateScope()) { - var context = scope.ServiceProvider.GetRequiredService(); - if (context is not null) - { - try + var provider = scope.ServiceProvider.GetRequiredService(); + using (var context = GetAccountDBContext(provider, 1)) + { + if (context is not null) { - using (var transaction = await context.CreateTransactionAsync(IsolationLevel.ReadUncommitted)) + try { - //select user - var selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); - if (selectUser is not null) + using (var transaction = await context.CreateTransactionAsync(IsolationLevel.ReadUncommitted)) { - if (selectUser.CPasswordHashed == loginModel?.Password) + //select user + var selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); + if (selectUser is not null) { - //select role - var selectRole = await context.TRoles.FindAsync(selectUser.CAuid); - if (selectRole != null) + if (selectUser.CPasswordHashed == loginModel?.Password) { - response.Role = (UserRole)Enum.Parse(typeof(UserRole), selectRole.CRoleId.ToString()); - response.RoleName = selectRole.CRoleName; - } + //select role + var selectRole = await context.TRoles.FindAsync(selectUser.CAuid); + if (selectRole != null) + { + response.Role = (UserRole)Enum.Parse(typeof(UserRole), selectRole.CRoleId.ToString()); + response.RoleName = selectRole.CRoleName; + } - // Session.Add(response); - - if (selectUser.CState == (byte)UserState.Active) - { - response.EC = ERROR_CODE.EC_OK; + Session.Add(response); + if (selectUser.CState == (byte)UserState.Active) + { + response.EC = ERROR_CODE.EC_OK; + } + else if (selectUser.CState == (byte)UserState.Inactive) + { + response.EC = ERROR_CODE.EC_USER_LOGIN_INAVTIVE; + } + else if (selectUser.CState == (byte)UserState.Block) + { + response.EC = ERROR_CODE.EC_USER_LOGIN_BLOCKED; + } } - else if (selectUser.CState == (byte)UserState.Inactive) + else { - response.EC = ERROR_CODE.EC_USER_LOGIN_INAVTIVE; - } - else if (selectUser.CState == (byte)UserState.Block) - { - response.EC = ERROR_CODE.EC_USER_LOGIN_BLOCKED; + response.EC = ERROR_CODE.EC_USER_LOGIN_INVALID_PASSWORD; } } else { - response.EC = ERROR_CODE.EC_USER_LOGIN_INVALID_PASSWORD; + response.EC = ERROR_CODE.EC_USER_LOGIN_NOT_EXIST; + Log4net.WriteLine($"{response.EC}", LogType.Error); } + await context.CloseTransactionAsync(transaction); } - else - { - response.EC = ERROR_CODE.EC_USER_LOGIN_NOT_EXIST; - Log4net.WriteLine($"{response.EC}", LogType.Error); - } - await context.CloseTransactionAsync(transaction); } - } - catch (Exception e) - { - Log4net.WriteLine($"Select User Transaction Error", LogType.Exception); - Log4net.WriteLine(e); + catch (Exception e) + { + Log4net.WriteLine($"Select User Transaction Error", LogType.Exception); + Log4net.WriteLine(e); + } } } } @@ -172,71 +173,74 @@ namespace AuthApi.Services return response; } - public async Task UpdateLoginInfo(LoginModel loginModel, string? RefreshToken = "") + public async Task UpdateLoginInfo(Login loginModel, string? RefreshToken = "") { bool result = false; bool transactionResult = true; using (var scope = _scopeFactory.CreateScope()) { - var context = scope.ServiceProvider.GetRequiredService(); - if (context is not null) + var provider = scope.ServiceProvider.GetRequiredService(); + using (var context = GetAccountDBContext(provider, 1)) { - var selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); - if (selectUser is not null) + if (context is not null) { - using (var transaction = await context.CreateTransactionAsync()) + var selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); + if (selectUser is not null) { - try + using (var transaction = await context.CreateTransactionAsync()) { - //user info - selectUser.CLastLoginDateTime = DateTime.Now; - context.Update(selectUser); - - //refresh token - var findRefreshToken = await context.TRefreshTokens.AsNoTracking().FirstOrDefaultAsync(x => x.CAuid == selectUser.CAuid); - //null이면(없으면) add - if (findRefreshToken == null) + try { - await context.AddAsync(new TRefreshToken + //user info + selectUser.CLastLoginDateTime = DateTime.Now; + context.Update(selectUser); + + //refresh token + var findRefreshToken = await context.TRefreshTokens.AsNoTracking().FirstOrDefaultAsync(x => x.CAuid == selectUser.CAuid); + //null이면(없으면) add + if (findRefreshToken == null) { - CAuid = selectUser.CAuid, - CRefreshToken = $"{RefreshToken}" - }); + await context.AddAsync(new TRefreshToken + { + CAuid = selectUser.CAuid, + CRefreshToken = $"{RefreshToken}" + }); + } + //있으면 update + else + { + findRefreshToken.CRefreshToken = $"{RefreshToken}"; + context.Update(findRefreshToken); + } + + //commit + Log4net.WriteLine(findRefreshToken?.ToJson(), LogType.Debug); + + result = true; } - //있으면 update - else + catch (Exception ex) { - findRefreshToken.CRefreshToken = $"{RefreshToken}"; - context.Update(findRefreshToken); + Log4net.WriteLine(ex); } - //commit - Log4net.WriteLine(findRefreshToken?.ToJson(), LogType.Debug); - - result = true; + transactionResult = await context.CloseTransactionAsync(transaction); } - catch (Exception ex) - { - Log4net.WriteLine(ex); - } - - transactionResult = await context.CloseTransactionAsync(transaction); } - } - else - { - Log4net.WriteLine($"Not Exist User {loginModel.UserID}", LogType.Error); - } + else + { + Log4net.WriteLine($"Not Exist User {loginModel.UserID}", LogType.Error); + } - //db error - if (transactionResult == false) - { - Log4net.WriteLine($"Transaction Error", LogType.Error); - } - else - { - Log4net.WriteLine($"Transaction Success", LogType.DB); + //db error + if (transactionResult == false) + { + Log4net.WriteLine($"Transaction Error", LogType.Error); + } + else + { + Log4net.WriteLine($"Transaction Success", LogType.DB); + } } } } @@ -244,9 +248,9 @@ namespace AuthApi.Services return result; } - public LogoutResponseModel LogoutUser(LogoutModel logoutModel) + public LogoutResponse LogoutUser(Logout logoutModel) { - LogoutResponseModel response = new LogoutResponseModel(); + LogoutResponse response = new LogoutResponse(); response.UserID = logoutModel.UserID; response.EC = ERROR_CODE.EC_USER_LOGOUT_FAILED; @@ -259,5 +263,11 @@ namespace AuthApi.Services return response; } + + private AccountDbContext? GetAccountDBContext(DbContextProvider provider, int dbID) + { + var connectionString = _configService?.GetConfig()?.DataBase?.Find(x => x.DBID == dbID); + return provider?.GetDBContext($"{connectionString?.DBName}"); + } } } diff --git a/Projects/WebApi/WebApi.Library.DBContext/DB/DBContext/AccountDB/Context/AccountDbContext.cs b/Projects/WebApi/WebApi.Library.DBContext/DB/DBContext/AccountDB/Context/AccountDbContext.cs index a053ff5..1775f3d 100644 --- a/Projects/WebApi/WebApi.Library.DBContext/DB/DBContext/AccountDB/Context/AccountDbContext.cs +++ b/Projects/WebApi/WebApi.Library.DBContext/DB/DBContext/AccountDB/Context/AccountDbContext.cs @@ -20,11 +20,7 @@ public partial class AccountDbContext : DbContext public virtual DbSet TRoles { get; set; } - public virtual DbSet TUsers { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) -#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. - => optionsBuilder.UseSqlServer("server=127.0.0.1; user id=SystemX; password=X; database=AccountDB; TrustServerCertificate=true;"); + public virtual DbSet TUsers { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) {