forked from AcaMate/AcaMate_API
443 lines
17 KiB
C#
443 lines
17 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Linq.Expressions;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using MySqlConnector;
|
|
using System.Linq;
|
|
|
|
using AcaMate.Common.Data;
|
|
using AcaMate.Common.Token;
|
|
using AcaMate.Common.Models;
|
|
|
|
using AcaMate.V1.Models;
|
|
using AcaMate.V1.Services;
|
|
|
|
namespace AcaMate.V1.Controllers;
|
|
|
|
/// <summary>
|
|
/// USER는 사용자가 자신의 데이터를 보거나 만들거나 하는 등 직접 사용하는 경우에 사용
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("/api/v1/in/user")]
|
|
[ApiExplorerSettings(GroupName = "사용자")]
|
|
public class UserController : ControllerBase
|
|
{
|
|
private readonly AppDbContext _dbContext;
|
|
private readonly ILogger<UserController> _logger;
|
|
private readonly JwtTokenService _jwtTokenService;
|
|
private readonly IRepositoryService _repositoryService;
|
|
|
|
public UserController(AppDbContext dbContext, ILogger<UserController> logger, JwtTokenService jwtTokenService,
|
|
IRepositoryService repositoryService)
|
|
{
|
|
_dbContext = dbContext;
|
|
_logger = logger;
|
|
_jwtTokenService = jwtTokenService;
|
|
_repositoryService = repositoryService;
|
|
}
|
|
|
|
[HttpGet]
|
|
[CustomOperation("회원 정보 조회", "회원 정보 조회 (자기자신)", "사용자")]
|
|
public async Task<IActionResult> GetUserData(string token)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
try
|
|
{
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
var uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "GetUserData");
|
|
|
|
var user = await _dbContext.User
|
|
.Where(u => u.uid == uid)
|
|
.Select(u => new User
|
|
{
|
|
uid = u.uid,
|
|
name = u.name,
|
|
auto_login_yn = u.auto_login_yn,
|
|
birth = u.birth,
|
|
device_id = u.device_id,
|
|
login_date = u.login_date,
|
|
type = u.type
|
|
})
|
|
.FirstOrDefaultAsync();
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", user));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return StatusCode(500, APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
[HttpGet("academy")]
|
|
[CustomOperation("학원 리스트 확인", "사용자가 등록된 학원 리스트 확인", "사용자")]
|
|
public async Task<IActionResult> ReadAcademyInfo(string token)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
try
|
|
{
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
var uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "ReadAcademyInfo");
|
|
|
|
var academies = await (from ua in _dbContext.UserAcademy
|
|
join a in _dbContext.Academy on ua.bid equals a.bid
|
|
where ua.uid == uid
|
|
select new AcademyName
|
|
{
|
|
bid = a.bid,
|
|
name = a.business_name
|
|
}).ToListAsync();
|
|
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상.", academies));
|
|
}
|
|
catch (TokenException tokenEx)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {tokenEx}");
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 토큰에 문제가 있음", Empty));
|
|
}
|
|
catch (RefreshRevokeException refreshEx)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {refreshEx}");
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 폐기된 리프레시 토큰", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {ex}");
|
|
return StatusCode(500, APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
|
|
[HttpGet("login")]
|
|
[CustomOperation("SNS 로그인", "로그인 후 회원이 있는지 확인", "사용자")]
|
|
public async Task<IActionResult> Login(string acctype, string snsId)
|
|
{
|
|
// API 동작 파라미터 입력 값 확인
|
|
if (string.IsNullOrEmpty(acctype) && string.IsNullOrEmpty(snsId))
|
|
return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "Login");
|
|
|
|
var login = await _dbContext.Login
|
|
.FirstOrDefaultAsync(l => l.sns_type == acctype && l.sns_id == snsId);
|
|
|
|
if (login != null)
|
|
{
|
|
// 로그인 정보가 존재 하는 상황
|
|
var user = await _dbContext.User
|
|
.FirstOrDefaultAsync(u => u.uid == login.uid);
|
|
|
|
// 회원 정보 없음
|
|
if (user == null) return Ok(APIResponse.Send("002", $"[{summary}], 회원 정보 오류", Empty));
|
|
|
|
// 정상적으로 User 테이블에도 있는것이 확인 됨
|
|
user.login_date = DateTime.Now;
|
|
await _dbContext.SaveChangesAsync();
|
|
|
|
// 토큰 생성은 로그인이 이제 되고 나서 한다.
|
|
var accessToken = _jwtTokenService.GenerateJwtToken(login.uid);
|
|
var refreshToken = _jwtTokenService.GenerateRefreshToken(login.uid);
|
|
_logger.LogInformation($"[{summary}] : {login.uid} = {accessToken}, {refreshToken}");
|
|
|
|
if (await _repositoryService.SaveData<RefreshToken>(refreshToken))
|
|
{
|
|
var logUser = new LogUser
|
|
{
|
|
uid = login.uid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = $"[{summary}] : 정상"
|
|
};
|
|
await _repositoryService.SaveData<LogUser>(logUser);
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상",
|
|
new { token = accessToken, refresh = refreshToken.refresh_token }));
|
|
}
|
|
else
|
|
{
|
|
var logUser = new LogUser
|
|
{
|
|
uid = login.uid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = $"[{summary}] : 실패"
|
|
};
|
|
await _repositoryService.SaveData<LogUser>(logUser);
|
|
|
|
return Ok(APIResponse.InternalSeverError($"[{summary}], 로그인 저장 실패"));
|
|
}
|
|
|
|
}
|
|
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 로그인 정보 없음", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {ex}");
|
|
return StatusCode(500, APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
[HttpPost("register")]
|
|
[CustomOperation("회원 가입", "사용자 회원 가입", "사용자")]
|
|
public async Task<IActionResult> UserRegister([FromBody] UserAll request)
|
|
{
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "UserRegister");
|
|
var localPartEmail = request.email.Substring(0, request.email.IndexOf('@'));
|
|
var uid = $"AM{localPartEmail}{DateTime.Now:yyyyMMdd}";
|
|
|
|
var user = new User
|
|
{
|
|
uid = uid,
|
|
name = request.name,
|
|
birth = request.birth,
|
|
type = request.type,
|
|
device_id = request.device_id,
|
|
auto_login_yn = request.auto_login_yn,
|
|
login_date = request.login_date,
|
|
push_token = request.push_token
|
|
};
|
|
var login = new Login
|
|
{
|
|
uid = uid,
|
|
sns_id = request.sns_id,
|
|
sns_type = request.sns_type
|
|
};
|
|
|
|
var permission = new Permission
|
|
{
|
|
uid = uid,
|
|
location_yn = request.location_yn,
|
|
camera_yn = request.camera_yn,
|
|
photo_yn = request.photo_yn,
|
|
push_yn = request.push_yn,
|
|
market_app_yn = request.market_app_yn,
|
|
market_sms_yn = request.market_sms_yn,
|
|
market_email_yn = request.market_email_yn
|
|
};
|
|
|
|
var contact = new Contact
|
|
{
|
|
uid = uid,
|
|
email = request.email,
|
|
phone = request.phone,
|
|
address = request.address
|
|
};
|
|
|
|
var logUser = new LogUser
|
|
{
|
|
uid = login.uid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = ""
|
|
};
|
|
|
|
var saveUser = await _repositoryService.SaveData<User>(user);
|
|
var saveLogin = await _repositoryService.SaveData<Login>(login);
|
|
var savePermission = await _repositoryService.SaveData<Permission>(permission);
|
|
var saveContact = await _repositoryService.SaveData<Contact>(contact);
|
|
if (saveUser && saveLogin && savePermission && saveContact)
|
|
{
|
|
|
|
var token = _jwtTokenService.GenerateJwtToken(uid);
|
|
var refreshToken = _jwtTokenService.GenerateRefreshToken(uid);
|
|
|
|
if (await _repositoryService.SaveData<RefreshToken>(refreshToken))
|
|
{
|
|
logUser.log = $"[{summary}] : 정상";
|
|
|
|
if (await _repositoryService.SaveData<LogUser>(logUser))
|
|
_logger.LogInformation($"[{summary}] : 로그 저장 성공");
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", new
|
|
{
|
|
token = token,
|
|
refresh = refreshToken.refresh_token
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
_logger.LogError($"[{summary}] : 토큰 저장 실패");
|
|
}
|
|
}
|
|
|
|
logUser.log = $"[{summary}] : 동작 실패";
|
|
await _repositoryService.SaveData<LogUser>(logUser);
|
|
|
|
return Ok(APIResponse.InternalSeverError());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {ex.Message}");
|
|
return BadRequest(APIResponse.UnknownError(ex.Message));
|
|
}
|
|
|
|
}
|
|
|
|
[HttpGet("logout")]
|
|
[CustomOperation("로그아웃", "사용자 로그아웃", "사용자")]
|
|
public async Task<IActionResult> Logout(string token)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
|
|
string summary = String.Empty;
|
|
try
|
|
{
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
var uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "UserRegister");
|
|
|
|
var refreshToken = await _dbContext.RefreshTokens.FirstOrDefaultAsync(r => r.uid == uid);
|
|
|
|
if (refreshToken != null)
|
|
{
|
|
refreshToken.revoke_Date = DateTime.Now;
|
|
await _repositoryService.SaveData<RefreshToken>(refreshToken);
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 로그아웃 정상", Empty));
|
|
}
|
|
|
|
// 리프레시 토큰이 없다?? 그럼 이거 무조건 문제지 (이유를 알 수 없는)
|
|
return Ok(APIResponse.UnknownError());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return StatusCode(500, APIResponse.UnknownError($"[{summary}], {ex.Message}"));
|
|
}
|
|
}
|
|
|
|
|
|
[HttpGet("cancel")]
|
|
[CustomOperation("회원 탈퇴", "사용자 탈퇴", "사용자")]
|
|
public async Task<IActionResult> Cancel(string token)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
var uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "Cancel");
|
|
|
|
|
|
// 여기서 애초에 토큰 관련 에러가 2개가 나오게 만들어져 있음
|
|
var user = await _dbContext.User.FirstOrDefaultAsync(u => u.uid == uid);
|
|
|
|
if (user == null)
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 회원 정보 확인 오류", Empty));
|
|
|
|
|
|
var logUser = new LogUser
|
|
{
|
|
uid = uid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = ""
|
|
};
|
|
|
|
string returnCode = "000";
|
|
string returnMsg = $"[{summary}], 정상";
|
|
if (await _repositoryService.DeleteData<User>(user))
|
|
logUser.log = $"[{summary}] : 정상";
|
|
else
|
|
{
|
|
logUser.log = $"[{summary}] : 실패";
|
|
returnMsg = $"[{summary}], 실패";
|
|
returnCode = "001";
|
|
}
|
|
|
|
if (!(await _repositoryService.SaveData<LogUser>(logUser))) _logger.LogError($"[{summary}] : 로그 저장 실패");
|
|
|
|
return Ok(APIResponse.Send(returnCode, returnMsg, Empty));
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return StatusCode(500, APIResponse.UnknownError($"[{summary}], {ex.Message}"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 근데 회원 정보를 변경하는게 뭐뭐를 변경해야 하는지 아직 정해진게 없어서 이건 일단 보류
|
|
/*
|
|
[HttpGet("set")]
|
|
[CustomOperation("회원 정보 변경", "회원 정보 변경", "사용자")]
|
|
public async Task<IActionResult> SetUserData(string token, string refresh) //, [FromBody])
|
|
{
|
|
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(refresh))
|
|
return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
summary = _repositoryService.ReadSummary(typeof(UserController), "Cancel");
|
|
|
|
|
|
// 여기서 애초에 토큰 관련 에러가 2개가 나오게 만들어져 있음
|
|
var validateToken = await _repositoryService.ValidateToken(token, refresh);
|
|
var user = await _dbContext.User.FirstOrDefaultAsync(u => u.uid == validateToken.uid);
|
|
|
|
}
|
|
catch (TokenException tokenEx)
|
|
{
|
|
return Ok(APIResponse.Send("101", $"[{summary}], 입력 받은 토큰의 문제", Empty));
|
|
}
|
|
catch (RefreshRevokeException refreshEx)
|
|
{
|
|
return Ok(APIResponse.Send("102", $"[{summary}], 폐기된 리프레시 토큰", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return StatusCode(500, APIResponse.UnknownError($"[{summary}], {ex.Message}"));
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
string uid = "";
|
|
if (token == "System") uid = "System";
|
|
else {
|
|
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(refresh)) return BadRequest(APIResponse.InvalidInputError());
|
|
if(!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
|
|
var validateToken = await _repositoryService.ValidateToken(token, refresh);
|
|
uid = validateToken.uid;
|
|
}
|
|
|
|
string summary = String.Empty;
|
|
try
|
|
{
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "GetUserData");
|
|
}
|
|
*/ |