using SystemX.Core.Model.Auth; using SystemX.Core.Services; using SystemX.Core; using WebApi.Library.Config; 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; namespace AuthApi.Services { public class AuthService { private readonly IServiceProvider _serviceProvider; private readonly IServiceScopeFactory _scopeFactory; private readonly ConfigService? _configService; private readonly DataBase? _accountDB; 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(); response.EC = ERROR_CODE.EC_USER_REGISTER_FAILED; response.UserID = registerModel.UserID; response.Role = registerModel.Role; response.RoleName = registerModel.Role.ToString(); //context using (var scope = _scopeFactory.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); if (context is not null) { var user = await context.TUsers.AsNoTracking().Where(x => x.CUserId.ToLower() == registerModel.UserID.ToLower()).ToListAsync(); if (user?.Count <= 0) { string auid = Guid.NewGuid().ToString(); //user TUser newUser = new TUser { 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; } } } } } return response; } /// /// select user(login) /// public async Task SelectUser(LoginModel loginModel) { //response LoginResponseModel response = new LoginResponseModel(); 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); //} //기존 로그인 체크 // 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 { using (var transaction = await context.CreateTransactionAsync(IsolationLevel.ReadUncommitted)) { //select user var selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); if (selectUser is not null) { if (selectUser.CPasswordHashed == loginModel?.Password) { //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; } 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 { response.EC = ERROR_CODE.EC_USER_LOGIN_INVALID_PASSWORD; } } 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); } } } } } return response; } public async Task UpdateLoginInfo(LoginModel 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 selectUser = await context.TUsers.AsNoTracking().FirstOrDefaultAsync(x => x.CUserId.ToLower() == loginModel!.UserID!.ToLower()); if (selectUser is not null) { using (var transaction = await context.CreateTransactionAsync()) { try { //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) { 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; } catch (Exception ex) { Log4net.WriteLine(ex); } transactionResult = await context.CloseTransactionAsync(transaction); } } 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); } } } return result; } public LogoutResponseModel LogoutUser(LogoutModel logoutModel) { LogoutResponseModel response = new LogoutResponseModel(); response.UserID = logoutModel.UserID; response.EC = ERROR_CODE.EC_USER_LOGOUT_FAILED; var session = Session.Find(x => x.UserID?.ToLower() == logoutModel?.UserID?.ToLower()); if (session != null) { Session.Remove(session); response.EC = ERROR_CODE.EC_OK; } return response; } } }