Ctrl K
ComunidadGuías…

Ferrite.Data/Repositories/SessionRepository.cs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2022-2026 Aykut Alparslan KOC

namespace Ferrite.Data.Repositories;

using Ferrite.TL;
using Ferrite.TL.baseLayer.dto;

public class SessionRepository : ISessionRepository
{
    private readonly IVolatileKVStore _store;
    private readonly IVolatileKVStore _storeByAuthKey;
    public SessionRepository(IVolatileKVStore store, IVolatileKVStore storeByAuthKey)
    {
        _store = store;
        _store.SetSchema(new TableDefinition("ferrite", "sessions_tl1",
            new KeyDefinition("pk",
                new DataColumn { Name = "session_id", Type = DataType.Long })));
        _storeByAuthKey = storeByAuthKey;
        _storeByAuthKey.SetSchema(new TableDefinition("ferrite", "sessions_by_auth_key_tl1",
            new KeyDefinition("pk",
                new DataColumn { Name = "auth_key_id", Type = DataType.Long })));
    }
    public bool PutSession(TLRemoteSession session, TimeSpan expire)
    {
        var row = session.AsRemoteSession();
        _store.Put(session.AsSpan().ToArray(), expire, row.SessionId);
        return true;
    }

    public TLRemoteSession? GetSession(long sessionId)
    {
        byte[]? bytes = _store.Get(sessionId);
        if (bytes is not { Length: > 0 }) return null;
        var value = new TLBytes(bytes, 0, bytes.Length);
        return value.Constructor == Constructors.baseLayer_RemoteSession
            ? (TLRemoteSession)value
            : throw new InvalidDataException("Remote session codec/version mismatch.");
    }

    public bool SetSessionTTL(long sessionId, TimeSpan expire)
    {
        _store.UpdateTtl(expire, sessionId);
        return true;
    }

    public bool DeleteSession(long sessionId)
    {
        _store.Delete(sessionId);
        return true;
    }

    public bool PutSessionForAuthKey(long authKeyId, long sessionId)
    {
        using var reference = SessionReference.Builder().SessionId(sessionId).Build();
        return _storeByAuthKey.ListAdd(DateTimeOffset.Now.ToUnixTimeMilliseconds(),
            reference.ToReadOnlySpan().ToArray(), null, authKeyId);
    }

    public bool DeleteSessionForAuthKey(long authKeyId, long sessionId)
    {
        using var reference = SessionReference.Builder().SessionId(sessionId).Build();
        return _storeByAuthKey.ListDelete(reference.ToReadOnlySpan().ToArray(), authKeyId);
    }

    public ICollection<long> GetSessionsByAuthKey(long authKeyId, TimeSpan expire)
    {
        var time = DateTimeOffset.Now - expire;
        _storeByAuthKey.ListDeleteByScore(time.ToUnixTimeMilliseconds(), authKeyId);
        var result = new List<long>();
        foreach (byte[] bytes in _storeByAuthKey.ListGet(authKeyId))
        {
            var value = new TLBytes(bytes, 0, bytes.Length);
            if (value.Constructor != Constructors.baseLayer_SessionReference)
            {
                throw new InvalidDataException("Session reference codec/version mismatch.");
            }
            result.Add(((TLSessionReference)value).AsSessionReference().SessionId);
        }
        return result;
    }
}