274 lines
12 KiB
C#
274 lines
12 KiB
C#
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 WebApi.Library.DBContext.DB.DBContext.AccountDB.Context;
|
|
using WebApi.Library.DBContext.DB.DBContext.AccountDB.Tables;
|
|
|
|
namespace AuthApi.Services
|
|
{
|
|
public class AuthService
|
|
{
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly IServiceScopeFactory _scopeFactory;
|
|
private readonly ConfigService<WebApiConfig>? _configService;
|
|
|
|
private static List<LoginResponse> Session = new List<LoginResponse>();
|
|
|
|
public AuthService(IServiceProvider serviceProvider, IServiceScopeFactory scopeFactory, ConfigService<WebApiConfig> configSerice)
|
|
{
|
|
_serviceProvider = serviceProvider;
|
|
_configService = configSerice;
|
|
_scopeFactory = scopeFactory;
|
|
}
|
|
|
|
/// <summary>
|
|
/// create new user
|
|
/// </summary>
|
|
public async Task<RegisterResponse> 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<DbContextProvider>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// select user(login)
|
|
/// </summary>
|
|
public async Task<LoginResponse> 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<DbContextProvider>();
|
|
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;
|
|
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<bool> UpdateLoginInfo(Login loginModel, string? RefreshToken = "")
|
|
{
|
|
bool result = false;
|
|
bool transactionResult = true;
|
|
|
|
using (var scope = _scopeFactory.CreateScope())
|
|
{
|
|
var provider = scope.ServiceProvider.GetRequiredService<DbContextProvider>();
|
|
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
|
|
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 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<AccountDbContext>($"{connectionString?.DBName}");
|
|
}
|
|
}
|
|
}
|