astral-api/Astral.Services/Services/UserPresenceService.cs

133 lines
4.2 KiB
C#
Raw Normal View History

2024-12-15 17:06:14 +01:00
// <copyright file="UserPresenceService.cs" company="alveus.dev">
// Copyright (c) alveus.dev. All rights reserved. Licensed under the MIT License.
// </copyright>
using Astral.Core.Entities;
using Astral.Core.Extensions;
using Astral.Core.RepositoryInterfaces;
using Astral.Services.Constants;
using Astral.Services.Dtos;
using Astral.Services.Exceptions;
2024-12-15 21:20:27 +01:00
using Astral.Services.Helpers;
2024-12-15 17:06:14 +01:00
using Astral.Services.Interfaces;
2024-12-15 21:20:27 +01:00
using AutoMapper;
2024-12-15 17:06:14 +01:00
using Injectio.Attributes;
namespace Astral.Services.Services;
/// <inheritdoc />
[RegisterScoped]
public class UserPresenceService : IUserPresenceService
{
private readonly IIdentityProvider _identityProvider;
private readonly ICryptographyService _cryptographyService;
private readonly IUserPresenceRepository _userPresenceRepository;
2024-12-15 21:20:27 +01:00
private readonly IMapper _mapper;
2024-12-15 17:06:14 +01:00
/// <summary>
/// Initializes a new instance of the <see cref="UserPresenceService"/> class.
/// </summary>
/// <param name="identityProvider">Instance of <see cref="IIdentityProvider"/>.</param>
/// <param name="cryptographyService">Instance of <see cref="ICryptographyService"/>.</param>
/// <param name="userPresenceRepository">Instance of <see cref="IUserPresenceRepository"/>.</param>
2024-12-15 21:20:27 +01:00
/// <param name="mapper">Instance of <see cref="IMapper"/>.</param>
2024-12-15 17:06:14 +01:00
public UserPresenceService(
IIdentityProvider identityProvider,
ICryptographyService cryptographyService,
2024-12-15 21:20:27 +01:00
IUserPresenceRepository userPresenceRepository,
IMapper mapper)
2024-12-15 17:06:14 +01:00
{
_identityProvider = identityProvider;
_cryptographyService = cryptographyService;
_userPresenceRepository = userPresenceRepository;
2024-12-15 21:20:27 +01:00
_mapper = mapper;
2024-12-15 17:06:14 +01:00
}
/// <inheritdoc />
public async Task HandleHeartbeat()
{
var userId = _identityProvider.GetUserId();
if (userId == Guid.Empty)
{
throw new UnauthorizedException();
}
var heartbeat = await _userPresenceRepository.FindByIdAsync(userId);
if (heartbeat is null)
{
heartbeat = new UserPresence()
{
2024-12-15 21:20:27 +01:00
CreatedAt = DateTime.UtcNow,
2024-12-15 17:06:14 +01:00
Id = userId,
LastHeartbeat = DateTime.UtcNow
};
await _userPresenceRepository.AddAsync(heartbeat);
}
else
{
heartbeat.LastHeartbeat = DateTime.UtcNow;
await _userPresenceRepository.UpdateAsync(heartbeat);
}
}
/// <inheritdoc />
public async Task ConsumeLocationHeartbeat(UserLocationHeartbeatDto heartbeat)
{
2024-12-15 21:20:27 +01:00
var userId = _identityProvider.GetUserId();
if (userId == Guid.Empty)
{
throw new UnauthorizedException();
}
var newHeartbeat = _mapper.Map<UserPresence>(heartbeat);
newHeartbeat.Id = userId;
var oldHeartbeat = await _userPresenceRepository.FindByIdAsync(userId) ?? new UserPresence()
{
CreatedAt = DateTime.UtcNow,
Id = userId
};
newHeartbeat.CreatedAt = oldHeartbeat.CreatedAt;
newHeartbeat.UpdatedAt = oldHeartbeat.UpdatedAt;
newHeartbeat.LastHeartbeat = oldHeartbeat.LastHeartbeat;
newHeartbeat = EntityHelpers.ApplyChanges(oldHeartbeat, newHeartbeat);
await _userPresenceRepository.UpdateAsync(newHeartbeat);
2024-12-15 17:06:14 +01:00
}
/// <inheritdoc />
public async Task ConsumePublicKey(Stream publicKey)
{
var userId = _identityProvider.GetUserId();
if (userId == Guid.Empty)
{
throw new UnauthorizedException();
}
var key = _cryptographyService.ConvertPublicKey(publicKey.ToByteArray(), PublicKeyType.Pkcs1PublicKey);
var heartbeat = await _userPresenceRepository.FindByIdAsync(userId);
if (heartbeat is null)
{
heartbeat = new UserPresence()
{
Id = userId,
LastHeartbeat = DateTime.UtcNow,
PublicKey = key
};
await _userPresenceRepository.AddAsync(heartbeat);
}
else
{
heartbeat.LastHeartbeat = DateTime.UtcNow;
heartbeat.PublicKey = key;
await _userPresenceRepository.UpdateAsync(heartbeat);
}
}
}