MyBookmark/Modules.User.Infrastructure.Database/Repositories/SessionRepository.cs

102 lines
4.1 KiB
C#

using Microsoft.EntityFrameworkCore;
using Modules.User.Database.Database;
using Modules.User.Database.Database.Entities;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
namespace Modules.User.Database.Repositories;
public class SessionRepository(UserDbContext context)
{
private readonly UserDbContext _context = context;
public async Task<List<Session>> GetAll(Guid accountId) =>
await _context.Sessions.Where(q => q.AccountId == accountId).ToListAsync();
public async Task<Session?> GetFirstOrDefaultWhere(Expression<Func<Session, bool>> predicate) =>
await _context.Sessions.SingleOrDefaultAsync(predicate);
public async Task<bool> SyncSessions(Guid accountId, List<Session> sessions, List<Guid>? forceUpdateSessionIds = null)
{
var accountSessions = await GetAll(accountId);
var deleteSessions = accountSessions.Except(sessions, new SessionComparer()).ToList();
var addSessions = sessions.Except(accountSessions, new SessionComparer()).ToList();
var updateSessions = sessions
.Where(q => accountSessions.Any(x => x.Id == q.Id && x.AccountId == q.AccountId)).ToList();
if (forceUpdateSessionIds?.Count > 0)
{
var sessionsToForceUpdate = forceUpdateSessionIds.Where(x => !deleteSessions.Any(z => z.Id.Equals(x)) &&
x != Guid.Empty && !updateSessions.Any(z => z.Id.Equals(x)));
updateSessions.AddRange(sessions.Where(q => sessionsToForceUpdate.Contains(q.Id)));
}
var result = true;
if (deleteSessions.Count != 0)
{
foreach(var session in deleteSessions)
{
_context.Sessions.Remove(accountSessions.First(q => q.Id == session.Id));
}
}
if (addSessions.Count != 0 && result)
{
_context.Sessions.AddRange(addSessions);
}
if (updateSessions.Count != 0 && result)
{
foreach (var session in updateSessions)
{
var existingSession = accountSessions.First(q => q.Id == session.Id);
existingSession.ClientInfo = new ClientInfo
{
UserAgent = session.ClientInfo.UserAgent,
Country = session.ClientInfo.Country,
Region = session.ClientInfo.Region,
};
if (existingSession.RefreshToken != session.RefreshToken ||
existingSession.ExpiredDate != session.ExpiredDate)
{
existingSession.RefreshToken = session.RefreshToken;
existingSession.ExpiredDate = session.ExpiredDate;
existingSession.LastUpdate = DateTime.UtcNow;
}
}
}
await _context.SaveChangesAsync();
return result;
}
private class SessionComparer : IEqualityComparer<Session>
{
public bool Equals(Session? x, Session? y)
{
return x != null && y != null &&
x.Id != default && y.Id != default && x.Id == y.Id &&
x.AccountId == y.AccountId;
}
public int GetHashCode([DisallowNull] Session obj)
{
return HashCode.Combine(obj.Id.GetHashCode(), obj.AccountId.GetHashCode());
}
}
//public async Task<bool> DeleteAsync(Session entity, bool cleanExpired = true)
//{
// var document = await _collection.FindOneAndDeleteAsync(q => q.RefreshToken == entity.RefreshToken);
// if (cleanExpired) await CleanAccountSessions(entity.AccountId);
// return document != null;
//}
//public async Task CleanAccountSessions(Guid accountId) => await DeleteAccountSessions(accountId);
//private async Task<bool> DeleteAccountSessions(Guid accountId, bool onlyExpired = true)
//{
// var filter = Builders<Session>.Filter.Eq(q => q.AccountId, accountId);
// if (onlyExpired) filter = filter & Builders<Session>.Filter.Lt(q => q.ExpiredDate, DateTime.UtcNow);
// var deleteResult = await _collection.DeleteManyAsync(filter);
// return deleteResult.IsAcknowledged;
//}
}