2026-07-23 13:54:06 -07:00

218 lines
7.8 KiB
C#

using Microsoft.Extensions.Caching.Distributed;
using qtc_api.Extensions;
using System.Security.Claims;
namespace qtc_api.Controllers
{
[Route("api/users")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
private readonly IDistributedCache _cache;
private readonly IHubContext<ChatHub> _chatGWContext;
public UsersController(IUserService userService, IDistributedCache distributedCache, IHubContext<ChatHub> chatGWContext)
{
_userService = userService;
_cache = distributedCache;
_chatGWContext = chatGWContext;
}
[HttpGet("all")]
[Authorize]
public async Task<ActionResult<ServiceResponse<List<UserInformationDto>>>> GetAllUsers()
{
var users = await _userService.GetAllUsers();
return Ok(users);
}
[HttpGet("user-info")]
[Authorize]
public async Task<ActionResult<ServiceResponse<UserInformationDto>>> GetUserInformation(string id)
{
var user = await _userService.GetUserInformationById(id);
return Ok(user);
}
[HttpGet("user-authorized")]
[Authorize]
public async Task<ActionResult<ServiceResponse<User>>> UserFromAuthorizeHead()
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
var id = claims.First().Value;
if (id != null)
{
var user = await _userService.GetUserById(id);
return Ok(user);
}
else
{
return BadRequest("Token did not contain an ID.");
}
}
else
{
return BadRequest("Header not found.");
}
}
[HttpPut("update")]
[Authorize]
public async Task<ActionResult<ServiceResponse<UserInformationDto>>> UpdateUserInformation(UserUpdateInformationDto user)
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
var id = claims.First().Value;
if (id != null && id == user.Id)
{
var updatedUser = await _userService.UpdateUserInfo(user);
if (updatedUser.Success && updatedUser.Data != null)
{
await _chatGWContext.Clients.All.SendAsync("UpdateUser", user);
await _chatGWContext.Clients.User(updatedUser.Data.Id).SendAsync("UpdateCurrentUser");
return Ok(updatedUser);
}
else return Ok();
}
else
{
return Unauthorized("You are not authorized to edit that user.");
}
}
else
{
return BadRequest("Session Expired.");
}
}
[HttpPost("upload-profile-pic")]
[Authorize]
public async Task<ActionResult<ServiceResponse<string>>> UploadOrUpdateProfilePic(string userId, IFormFile file)
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
var id = claims.First().Value;
if (id != null && id == userId)
{
if (file.Length > 3000000)
{
return BadRequest("File Is Above Limit.");
}
var response = await _userService.UpdateUserPic(userId, file);
var res = await _userService.GetUserById(id);
User? user = res.Data;
UserInformationDto dto = new();
if (user != null)
dto.MapToUser(user);
await _chatGWContext.Clients.All.SendAsync("UpdateUser", dto);
// always try to overwrite cache when updating pfp
string recordId = $"UserPfp_{userId}";
using var stream = file.OpenReadStream();
using var ms = new MemoryStream();
stream.CopyTo(ms);
await _cache.SetImageAsync(recordId, ms.ToArray(), TimeSpan.FromHours(1));
await _chatGWContext.Clients.User(id).SendAsync("UpdateCurrentUser");
return Ok(response);
}
else
{
return BadRequest("You are not permitted to edit that user.");
}
}
else
{
return BadRequest("No Identity.");
}
}
[HttpGet("profile-pic/{userId}")]
[Authorize]
public async Task<ActionResult> GetUserProfilePicture(string userId)
{
string recordId = $"UserPfp_{userId}";
byte[]? pfpBytes = await _cache.GetImageAsync(recordId);
var result = new ServiceResponse<FileContentResult>();
if (pfpBytes == null)
{
result = await _userService.GetUserPic(userId);
if (result != null && result.Success && result.Data != null)
{
pfpBytes = result.Data.FileContents;
await _cache.SetImageAsync(recordId, pfpBytes, TimeSpan.FromHours(1));
}
}
else
{
// explicitly set from cache
result.Success = true;
result.Data = new FileContentResult(pfpBytes, "image/jpeg");
}
if (result != null && result.Success != false)
{
return result.Data!;
}
else if (result!.Message == "User Does Not Have A Profile Picture." || result!.Message == "User Content Folder Does Not Exist Yet.")
{
return BadRequest("User has no profile picture.");
}
else
{
return BadRequest("Failed To Get Profile Picture.");
}
}
[HttpDelete("delete-user")]
[Authorize(Roles = "Admin")]
public async Task<ActionResult<ServiceResponse<User>>> DeleteUserById(string id)
{
var result = await _userService.DeleteUser(id);
await _chatGWContext.Clients.All.SendAsync("RefreshUserLists");
if (result != null && result.Success && result.Data != null) await _chatGWContext.Clients.User(result.Data.Id).SendAsync("ForceSignOut");
return Ok(result);
}
[HttpPost("update-user-currency")]
[Authorize]
public async Task<ActionResult<ServiceResponse<int>>> UpdateUserCurrency(int amount, bool isSpinClaim)
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
var id = claims.First().Value;
var _res = await _userService.AddCurrencyToUser(id, amount, isSpinClaim);
if (_res.Success)
{
await _chatGWContext.Clients.User(id).SendAsync("UpdateCurrentUser");
return Ok(_res);
}
else return Ok(new ServiceResponse<int> { Success = false, Message = "Identity Has No User ID" });
}
else return Ok(new ServiceResponse<int> { Success = false, Message = "No Identity" });
}
}
}