async Task<string> GenerateJwtTokenAsync(User user)

This commit is contained in:
Artemy
2025-07-02 15:26:27 +07:00
parent 0967fe1b4e
commit 0669614a5e
13 changed files with 131 additions and 22 deletions
@@ -40,14 +40,14 @@ public class JwtServiceTests
} }
[Test] [Test]
public void GenerateJwtToken_ShouldReturnValidJwtString() public async Task GenerateJwtToken_ShouldReturnValidJwtString()
{ {
// Arrange // Arrange
var user = _fixture.Create<User>(); var user = _fixture.Create<User>();
var expectedRole = "User"; var expectedRole = "User";
_invitesServiceMock.Setup(s => s.GetRoleAsync(user)).Returns(Task.FromResult(expectedRole)); _invitesServiceMock.Setup(s => s.GetRoleAsync(user)).Returns(Task.FromResult(expectedRole));
// Act // Act
var tokenString = _jwtService.GenerateJwtToken(user); var tokenString = await _jwtService.GenerateJwtTokenAsync(user);
// Assert // Assert
Assert.That(tokenString, Is.Not.Null.And.Not.Empty); Assert.That(tokenString, Is.Not.Null.And.Not.Empty);
@@ -23,17 +23,36 @@ public class UsersController : Controller
[HttpGet] [HttpGet]
public async Task<IActionResult> AllUsers() public async Task<IActionResult> AllUsers()
{
try
{ {
_logger.LogInformation("Getting all users by administrator"); _logger.LogInformation("Getting all users by administrator");
var read = await _users.GetAllUsersAsync(); var read = await _users.GetAllUsersAsync();
return Ok(BuildUserDtos(read)); return Ok(BuildUserDtos(read));
} }
catch (Exception e)
{
_logger.LogError(e, e.Message);
return StatusCode(500, e.Message);
}
}
[HttpGet("{id:guid}")] [HttpGet("{id:guid}")]
public async Task<IActionResult> GetUserById(Guid id) public async Task<IActionResult> GetUserById(Guid id)
{ {
return Ok(id); try
{
_logger.LogInformation($"Getting user {id} by administrator");
var read = await _users.GetUserById(id);
return Ok(BuildUserDtos([read]).First());
}
catch (Exception e)
{
_logger.LogError(e, e.Message);
return StatusCode(500, e.Message);
}
} }
private List<UserResponse> BuildUserDtos(IEnumerable<User> users) => users.Select(user => new UserResponse private List<UserResponse> BuildUserDtos(IEnumerable<User> users) => users.Select(user => new UserResponse
+50
View File
@@ -0,0 +1,50 @@
using Govor.Application.Interfaces;
using Govor.Contracts.Requests;
using Govor.Core.Models;
using Govor.Core.Repositories.MediasAttachments;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Govor.API.Controllers;
[ApiController]
[Route("api/media")]
[Authorize(Roles = "User,Admin")]
public class MediaController : Controller
{
private readonly ILogger<MediaController> _logger;
private readonly IStorageService _storageService;
private readonly IMediaAttachmentsRepository _repository;
public MediaController(ILogger<MediaController> logger, IStorageService storageService)
{
_logger = logger;
_storageService = storageService;
}
[HttpPost("upload")]
[RequestSizeLimit(100_000_000)]// ~100MB
public async Task<IActionResult> Upload([FromForm] MediaUploadRequest request)
{
try
{
var url = await _storageService.SaveAsync(request.Data,request.FileName);
var mediaId = Guid.NewGuid();
_repository.AddAsync(new MediaAttachments()
{
Id = mediaId,
FilePath = url,
EncryptedKey = request.EncryptedKey,
MimeType = request.MimeType,
Type = request.Type,
});
return Ok(mediaId);
}
catch (Exception ex)
{
return StatusCode(500, ex);
}
}
}
+10 -9
View File
@@ -1,4 +1,5 @@
using System.Security.Claims; using System.Security.Claims;
using Govor.Contracts.Requests.SignalR;
using Govor.Core.Models; using Govor.Core.Models;
using Govor.Core.Repositories.Users; using Govor.Core.Repositories.Users;
using Govor.Data.Repositories.Exceptions; using Govor.Data.Repositories.Exceptions;
@@ -48,19 +49,19 @@ public class ChatsHub : Hub
} }
public async Task Send(string message, Guid toUserId) public async Task Send(MessageRequest request)
{ {
// Валидация входных данных // Валидация входных данных
if (string.IsNullOrWhiteSpace(message)) if (string.IsNullOrWhiteSpace(request.EncryptedContent))
{ {
_logger.LogWarning("Empty message received from user {UserId}", GetUserId()); _logger.LogWarning("Empty message received from user {UserId}", GetUserId());
throw new ArgumentException("Message cannot be empty", nameof(message)); throw new ArgumentException("Message cannot be empty", nameof(request.EncryptedContent));
} }
var senderId = GetUserId(); var senderId = GetUserId();
// Проверка существования получателя // Проверка существования получателя
try /*try
{ {
await _usersRepository.FindByIdAsync(toUserId); await _usersRepository.FindByIdAsync(toUserId);
} }
@@ -73,19 +74,19 @@ public class ChatsHub : Hub
{ {
_logger.LogWarning("Invalid recipient userId received from user {UserId}", GetUserId()); _logger.LogWarning("Invalid recipient userId received from user {UserId}", GetUserId());
throw; throw;
} }*/
try try
{ {
_logger.LogInformation("Message sent from {SenderId} to {RecipientId}: {Message}", senderId, toUserId, message); _logger.LogInformation("Message sent from {SenderId} to {RecipientId} at {UtcNow}", senderId, request.RecipientId, DateTime.UtcNow);
// Отправка сообщения отправителю и получателю // Отправка сообщения отправителю и получателю
await Clients.Group(toUserId.ToString()).SendAsync("Receive", message, senderId); //await Clients.Group(request.RecipientId.ToString()).SendAsync("Receive", message, senderId);
await Clients.Group(senderId.ToString()).SendAsync("Receive", message, senderId); // Clients.Group(senderId.ToString()).SendAsync("Receive", message, senderId);
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error sending message from {SenderId} to {RecipientId}", senderId, toUserId); //_logger.LogError(ex, "Error sending message from {SenderId} to {RecipientId}", senderId, toUserId);
throw; throw;
} }
} }
@@ -26,4 +26,11 @@ public class UsersService : IUsersAdministration
return new List<User>(); return new List<User>();
} }
} }
public async Task<User> GetUserById(Guid userId)
{
var result = await _usersRepository.FindByIdAsync(userId);
return result;
}
} }
@@ -4,5 +4,5 @@ namespace Govor.API.Services.Authentication.Interfaces;
public interface IJwtService public interface IJwtService
{ {
string GenerateJwtToken(User user); Task<string> GenerateJwtTokenAsync(User user);
} }
@@ -5,4 +5,5 @@ namespace Govor.API.Services.AdminsStuff.Interfaces;
public interface IUsersAdministration public interface IUsersAdministration
{ {
Task<List<User>> GetAllUsersAsync(); Task<List<User>> GetAllUsersAsync();
Task<User> GetUserById(Guid userId);
} }
+2 -2
View File
@@ -57,7 +57,7 @@ public class AuthService : IAccountService
SetRole(user, invitation); SetRole(user, invitation);
return _jwtService.GenerateJwtToken(user); return await _jwtService.GenerateJwtTokenAsync(user);
} }
@@ -71,7 +71,7 @@ public class AuthService : IAccountService
if (_passwordHasher.Verify(password, user.PasswordHash) == false) if (_passwordHasher.Verify(password, user.PasswordHash) == false)
throw new LoginUserException(); throw new LoginUserException();
return _jwtService.GenerateJwtToken(user); return await _jwtService.GenerateJwtTokenAsync(user);
} }
private async void SetRole(User user, Invitation invitation) private async void SetRole(User user, Invitation invitation)
+2 -2
View File
@@ -19,12 +19,12 @@ public class JwtService : IJwtService
_invitesService = invitesService; _invitesService = invitesService;
} }
public string GenerateJwtToken(User user) public async Task<string> GenerateJwtTokenAsync(User user)
{ {
var claims = new[] var claims = new[]
{ {
new Claim("userId", user.Id.ToString()), new Claim("userId", user.Id.ToString()),
new Claim(ClaimTypes.Role, _invitesService.GetRoleAsync(user).Result, ClaimValueTypes.String) new Claim(ClaimTypes.Role, await _invitesService.GetRoleAsync(user), ClaimValueTypes.String)
}; };
var singing = new SigningCredentials( var singing = new SigningCredentials(
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
using Govor.Core.Models;
namespace Govor.Contracts.Requests;
public class MediaUploadRequest
{
public byte[] Data { get; set; }
public string FileName { get; set; }
public string EncryptedKey { get; set; } = string.Empty;
public MediaType Type { get; set; }
public string MimeType { get; set; } = string.Empty;
}
@@ -0,0 +1,11 @@
using Govor.Core.Models;
namespace Govor.Contracts.Requests.SignalR;
public record MediaReference
{
public Guid MediaId { get; init; }
public string EncryptedKey { get; init; } = string.Empty;
public MediaType Type { get; init; }
public string MimeType { get; init; } = string.Empty;
}
@@ -0,0 +1,9 @@
namespace Govor.Contracts.Requests.SignalR;
public record MessageRequest
{
public Guid RecipientId { get; init; }
public string EncryptedContent { get; init; } = string.Empty;
public Guid? ReplyToMessageId { get; set; }
public List<MediaReference> MediaAttachments { get; set; } = new();
}
-2
View File
@@ -4,11 +4,9 @@ public class MediaAttachments
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid MessageId { get; set; } public Guid MessageId { get; set; }
public MediaType Type { get; set; } public MediaType Type { get; set; }
public string FilePath { get; set; } = string.Empty; // local path in filesystem public string FilePath { get; set; } = string.Empty; // local path in filesystem
public string MimeType { get; set; } = string.Empty; public string MimeType { get; set; } = string.Empty;
public string? EncryptedKey { get; set; } public string? EncryptedKey { get; set; }
public Message Message { get; set; } = null!; public Message Message { get; set; } = null!;