mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
Add cryptographic session key management for users
Introduces a new cryptographic key management system for user sessions, including models, DTOs, interfaces, and services for handling identity keys, signed pre-keys, and one-time pre-keys. Updates the SessionKeysController and DI configuration to use the new services. Adds related EF Core configurations and migrations, and updates the UserSession model to reference the new UserCryptoSession. Removes the obsolete ISessionKeyService interface.
This commit is contained in:
@@ -11,6 +11,7 @@ using Govor.Application.Interfaces.Medias;
|
||||
using Govor.Application.Interfaces.Messages;
|
||||
using Govor.Application.Interfaces.UserOnlineStatus;
|
||||
using Govor.Application.Interfaces.UserSession;
|
||||
using Govor.Application.Interfaces.UserSession.Crypto;
|
||||
using Govor.Application.Services;
|
||||
using Govor.Application.Services.Authentication;
|
||||
using Govor.Application.Services.Friends;
|
||||
@@ -18,6 +19,7 @@ using Govor.Application.Services.Medias;
|
||||
using Govor.Application.Services.Messages;
|
||||
using Govor.Application.Services.UserOnlineStatus;
|
||||
using Govor.Application.Services.UserSessions;
|
||||
using Govor.Application.Services.UserSessions.Crypto;
|
||||
using Govor.Core.Infrastructure.Extensions;
|
||||
using Govor.Core.Infrastructure.Validators;
|
||||
using Govor.Core.Models;
|
||||
@@ -91,6 +93,10 @@ public static class ConfigurationProgramExtensions
|
||||
|
||||
services.AddScoped<IUserSessionReader, UserSessionReader>();
|
||||
services.AddScoped<IUserSessionRevoker, UserSessionRevoker>();
|
||||
|
||||
services.AddScoped<ISessionKeyAttacher, SessionKeyAttacher>();
|
||||
services.AddScoped<ISessionKeysReader, SessionKeysReader>();
|
||||
services.AddScoped<IOneTimePreKeysRotator, OneTimePreKeysRotator>();
|
||||
}
|
||||
|
||||
public static void AddRepositories(this IServiceCollection services)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Govor.Application.Interfaces.Friends;
|
||||
using Govor.Application.Interfaces.Infrastructure.Extensions;
|
||||
using Govor.Application.Interfaces.UserSession;
|
||||
using Govor.Application.Interfaces.UserSession.Crypto;
|
||||
using Govor.Contracts.Requests;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -12,32 +15,96 @@ namespace Govor.API.Controllers.Authentication;
|
||||
public class SessionKeysController : Controller
|
||||
{
|
||||
private readonly ILogger<SessionKeysController> _logger;
|
||||
private readonly IFriendshipService _friendshipService;
|
||||
private readonly ICurrentUserSessionService _currentSession;
|
||||
private readonly ISessionKeyAttacher _sessionKeyAttacher;
|
||||
private readonly ISessionKeysReader _sessionKeysReader;
|
||||
private readonly IOneTimePreKeysRotator _oneTimePreKeysRotator;
|
||||
private readonly ICurrentUserService _currentUser;
|
||||
/*
|
||||
|
||||
public SessionKeysController(
|
||||
ILogger<SessionKeysController> logger,
|
||||
IFriendshipService friendshipService,
|
||||
ICurrentUserSessionService currentSession,
|
||||
ISessionKeyAttacher sessionKeyAttacher,
|
||||
ISessionKeysReader sessionKeysReader,
|
||||
ICurrentUserService currentUser)
|
||||
{
|
||||
_logger = logger;
|
||||
_friendshipService = friendshipService;
|
||||
_currentSession = currentSession;
|
||||
_sessionKeyAttacher = sessionKeyAttacher;
|
||||
_sessionKeysReader = sessionKeysReader;
|
||||
_currentUser = currentUser;
|
||||
}
|
||||
|
||||
[HttpPost("keys")]
|
||||
public async Task<IActionResult> UploadSessionKeys([FromBody] UploadKeysRequest request)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if(request.OneTimePreKeys.Count > 100)
|
||||
return BadRequest("Too many one time pre keys");
|
||||
|
||||
var sessionId = _currentSession.GetUserSessionId();
|
||||
|
||||
await _sessionKeyService.AttachKeysAsync(sessionId, request.PublicEncryptionKey, request.PublicSigningKey);
|
||||
await _sessionKeyAttacher.AttachKeysAsync(sessionId,
|
||||
request.IdentityKey,
|
||||
request.SignedPreKey,
|
||||
request.SignedPreKeySignature,
|
||||
request.OneTimePreKeys);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("users/{userId}/keys")]
|
||||
public async Task<IActionResult> GetUserPublicKeys(Guid userId)
|
||||
{
|
||||
var requesterId = _currentUserService.UserId;
|
||||
var requesterId = _currentUser.GetCurrentUserId();
|
||||
|
||||
if (!await _friendshipService.AreFriendsAsync(requesterId, userId))
|
||||
if (!(await _friendshipService.GetFriendsAsync(userId)).Select(u => u.Id).Contains(requesterId))
|
||||
return Forbid("You can only access keys of your friends");
|
||||
|
||||
var keys = await _sessionKeyService.GetAllActiveKeysAsync(userId);
|
||||
var keys = await _sessionKeysReader.GetAllActiveKeysAsync(userId);
|
||||
|
||||
return Ok(keys);
|
||||
}
|
||||
|
||||
[HttpPost("keys/rotate")]
|
||||
public async Task<IActionResult> RotateOneTimePreKeys([FromBody] RotateOneTimePreKeysRequest request)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (request.NewOneTimePreKeys.Count > 100)
|
||||
return BadRequest("Too many new one time pre keys");
|
||||
|
||||
var sessionId = _currentSession.GetUserSessionId();
|
||||
|
||||
await _oneTimePreKeysRotator.RotateOneTimePreKeysAsync(sessionId, request.NewOneTimePreKeys);
|
||||
|
||||
return Ok("One-Time PreKeys rotated successfully.");
|
||||
}
|
||||
|
||||
[HttpGet("keys/remaining")]
|
||||
public async Task<IActionResult> GetRemainingOneTimePreKeysCount()
|
||||
{
|
||||
var sessionId = _currentSession.GetUserSessionId();
|
||||
|
||||
var count = await _sessionKeysReader.GetRemainingOneTimePreKeysCountAsync(sessionId);
|
||||
|
||||
return Ok(new { remaining = count });
|
||||
}
|
||||
|
||||
[HttpPost("keys/{preKeyId}/used")]
|
||||
public async Task<IActionResult> MarkOneTimePreKeyAsUsed([FromRoute] Guid preKeyId)
|
||||
{
|
||||
var sessionId = _currentSession.GetUserSessionId();
|
||||
|
||||
await _oneTimePreKeysRotator.MarkOneTimePreKeyAsUsedAsync(sessionId, preKeyId);
|
||||
|
||||
return Ok("Marked as used.");
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
@@ -16,5 +16,8 @@
|
||||
},
|
||||
"JwtRefreshOption": {
|
||||
"RefreshTokenLifetimeDays": 30
|
||||
},
|
||||
"EncryptionOption": {
|
||||
"Secret": "4r8B2j9kP5mX7nQwE2zY3A=="
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user