using System.Globalization; using System.Security.Claims; using Amazon.Auth.AccessControlPolicy; using Asp.Versioning; using JwtRoleAuthentication.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using ServerCommon; using ServerCommon.BusinessLogDomain; using ServerCommon.UGQ.Models; using Swashbuckle.AspNetCore.Annotations; using UGQApiServer.Controllers.Common; using UGQApiServer.Converter; using UGQApiServer.Models; using UGQDataAccess.Repository.Models; using UGQDataAccess.Service; using UGQDatabase.Models; using UGQDataAccess.Logs; using ServerBase; namespace UGQApiServer.Controllers.Admin; [ApiController] [ApiVersion("1.0")] [ApiExplorerSettings(GroupName = "admin")] [Route("api/v{version:apiVersion}/[controller]")] [UGQAdminApi] public class AdminController : ControllerBase { AdminService _adminService; TokenService _tokenService; public AdminController(AdminService adminService, TokenService tokenService) { _adminService = adminService; _tokenService = tokenService; } /// /// 어드민 계정 추가 /// // [Authorize(Roles = "Admin")] [HttpPost] [Route("signup")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK, Type = typeof(AdminSignupResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task signup([FromBody] AdminSignupRequest request) { var entity = await _adminService.signup(request.Username, request.Password, UGQAccountRole.Service); if (entity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(new AdminSignupResponse { Username = entity.Username, Role = entity.Role, }); } /// /// 어드민 로그인 /// [HttpPost] [Route("login")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK, Type = typeof(AdminLoginResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task login([FromBody] AdminLoginRequest request) { var entity = await _adminService.login(request.Username, request.Password); if(entity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); var accessToken = _tokenService.CreateAdminToken(entity.Username, entity.Role); var refreshToken = _tokenService.GenerateRefreshToken(); DateTime refreshTokenExpryTime = DateTime.Now.AddDays(7); if (await _adminService.saveRefreshToken(entity.Id, refreshToken, refreshTokenExpryTime) == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); List business_logs = [ new UgqApiAdminLoginBusinessLog(entity.Username), ]; var log_action = new LogActionEx(LogActionType.UgqApiAdminLogin); UgqApiBusinessLogger.collectLogs(log_action, entity, business_logs); return Results.Ok(new AdminLoginResponse { Username = entity.Username, Role = entity.Role, AccessToken = accessToken, RefreshToken = refreshToken }); } /// /// 어드민 패스워드 변경 /// [Authorize] [HttpPost] [Route("change-password")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK, Type = typeof(AdminChangePaswordResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task changePassowrd([FromBody] AdminChangePaswordRequest request) { var username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value; if (username == null) return Results.Unauthorized(); var entity = await _adminService.changePassword(username, request.NewPassword); if (entity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(new AdminChangePaswordResponse { }); } /// /// 어드민 패스워드 변경 /// [HttpPost] [Route("update-password")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK, Type = typeof(AdminUpdatePaswordResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task updatePassowrd([FromBody] AdminUpdatePaswordRequest request) { var entity = await _adminService.changePassword(request.Username, request.NewPassword); if (entity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(new AdminUpdatePaswordResponse { }); } /// /// 토큰 리프레쉬 /// [HttpPost] [Route("refresh")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK, Type = typeof(RefreshTokenResponse))] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task Refresh([FromBody] RefreshTokenRequest request) { var principal = _tokenService.GetPrincipalFromExpiredToken(request.AccessToken); var username = principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value; if (username == null) return Results.Unauthorized(); var entity = await _adminService.get(username); if (entity is null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); if (entity.RefreshToken != request.RefreshToken || entity.RefreshTokenExpiryTime <= DateTime.Now) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqInvalidToken)); var accessToken = _tokenService.CreateAdminToken(entity.Username, entity.Role); var refreshToken = _tokenService.GenerateRefreshToken(); if (await _adminService.saveRefreshToken(entity.Id, refreshToken, null) == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(new RefreshTokenResponse { AccessToken = accessToken, RefreshToken = refreshToken, }); } [Authorize] [HttpPost] [Route("logout")] [Produces("application/json")] [SwaggerResponse(StatusCodes.Status200OK)] [SwaggerResponse(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))] public async Task Logout() { var username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value; if (username == null) return Results.Unauthorized(); if (await _adminService.deleteRefreshToken(username) == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(); } }