using SystemX.Core.Model.Auth; using SystemX.Core.Services; using SystemX.Core; using WebApi.Library.Config; using System.Data; using SystemX.Core.DB; using Microsoft.EntityFrameworkCore; namespace AuthApi.Services { public class AuthService { private readonly IServiceProvider _serviceProvider; private readonly IServiceScopeFactory _scopeFactory; private readonly ConfigService? _configService; private static List Session = new List(); public AuthService(IServiceProvider serviceProvider, IServiceScopeFactory scopeFactory, ConfigService configSerice) { _serviceProvider = serviceProvider; _configService = configSerice; _scopeFactory = scopeFactory; } /// /// create new user /// 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; response.RoleName = registerModel.Role.ToString(); //context using (var scope = _scopeFactory.CreateScope()) { var provider = scope.ServiceProvider.GetRequiredService(); using (var context = GetAccountDBContext(provider, 1)) { 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(Login loginModel) { //response 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); } //기존 로그인 체크 if (Session.Exists(x => x.UserID == $"{loginModel.UserID?.ToLower()}") == false) { if (loginModel != null) { //context using (var scope = _scopeFactory.CreateScope()) { var provider = scope.ServiceProvider.GetRequiredService(); using (var context = GetAccountDBContext(provider, 1)) { 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; LogXnet.WriteLine($"{response.EC}", LogXLabel.Error); } await context.CloseTransactionAsync(transaction); } } catch (Exception e) { LogXnet.WriteLine($"Select User Transaction Error", LogXLabel.Exception); LogXnet.WriteLine(e); } } } } } } return response; } public async Task UpdateLoginInfo(Login loginModel, string? RefreshToken = "") { bool result = false; bool transactionResult = true; using (var scope = _scopeFactory.CreateScope()) { var provider = scope.ServiceProvider.GetRequiredService(); using (var context = GetAccountDBContext(provider, 1)) { 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 LogXnet.WriteLine($"{findRefreshToken?.ToJson()}", LogXLabel.Debug); result = true; } catch (Exception ex) { LogXnet.WriteLine(ex); } transactionResult = await context.CloseTransactionAsync(transaction); } } else { LogXnet.WriteLine($"Not Exist User {loginModel.UserID}", LogXLabel.Error); } //db error if (transactionResult == false) { LogXnet.WriteLine($"Transaction Error", LogXLabel.Error); } else { LogXnet.WriteLine($"Transaction Success", LogXLabel.DB); } } } } return result; } public LogoutResponse LogoutUser(Logout logoutModel) { LogoutResponse response = new LogoutResponse(); 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; } private AccountDBContext? GetAccountDBContext(DbContextProvider provider, int dbID) { var connectionString = _configService?.GetConfig()?.DataBase?.Find(x => x.DBID == dbID); return provider?.GetDBContext(Convert.ToInt32(connectionString?.DBID)); } } }