Ctrl K
ComunidadGuías…

Ferrite.Data/Repositories/BoundAuthKeyRepository.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 BoundAuthKeyRepository : IBoundAuthKeyRepository
{
    private readonly IVolatileKVStore _storeTemp;
    private readonly IVolatileKVStore _storeAuth;
    private readonly IVolatileKVStore _storeBound;
    public BoundAuthKeyRepository(IVolatileKVStore storeTemp, IVolatileKVStore storeAuth,
         IVolatileKVStore storeBound)
    {
        _storeTemp = storeTemp;
        _storeAuth = storeAuth;
        _storeBound = storeBound;
        _storeTemp.SetSchema(new TableDefinition("ferrite", "bound_auth_keys_temp_tl1",
            new KeyDefinition("pk",
                new DataColumn { Name = "temp_auth_key_id", Type = DataType.Long })));
        _storeAuth.SetSchema(new TableDefinition("ferrite", "bound_auth_keys_auth_tl1",
            new KeyDefinition("pk",
                new DataColumn { Name = "auth_key_id", Type = DataType.Long })));
        _storeBound.SetSchema(new TableDefinition("ferrite", "bound_auth_keys_by_auth_tl1",
            new KeyDefinition("pk",
                new DataColumn { Name = "auth_key_id", Type = DataType.Long })));
    }
    
    public bool PutBoundAuthKey(long tempAuthKeyId, long authKeyId, TimeSpan expiresIn)
    {
        using var auth = BoundAuthKey.Builder().AuthKeyId(authKeyId).Build();
        using var temp = BoundTempAuthKey.Builder().TempAuthKeyId(tempAuthKeyId).Build();
        _storeTemp.Put(auth.ToReadOnlySpan().ToArray(), expiresIn, tempAuthKeyId);
        _storeAuth.Put(temp.ToReadOnlySpan().ToArray(), expiresIn, authKeyId);
        _storeBound.ListAdd(DateTimeOffset.Now.ToUnixTimeMilliseconds() + (long)expiresIn.TotalMilliseconds,
            temp.ToReadOnlySpan().ToArray(), expiresIn, authKeyId);
        return true;
    }

    public long? GetBoundAuthKey(long tempAuthKeyId)
    {
        var authBytes = _storeTemp.Get(tempAuthKeyId);
        if (authBytes == null)
        {
            return null;
        }
        var authKeyId = ReadAuthKey(authBytes);
        var tempBytes = _storeAuth.Get(authKeyId);
        if (tempBytes == null)
        {
            return null;
        }
        var boundKey = ReadTempAuthKey(tempBytes);
        if (boundKey == tempAuthKeyId)
        {
            return authKeyId;
        }
        return null;
    }

    public async ValueTask<long?> GetBoundAuthKeyAsync(long tempAuthKeyId)
    {
        var authBytes = await _storeTemp.GetAsync(tempAuthKeyId);
        if (authBytes == null)
        {
            return null;
        }
        var authKeyId = ReadAuthKey(authBytes);
        var tempBytes = await _storeAuth.GetAsync(authKeyId);
        if (tempBytes == null)
        {
            return null;
        }
        var boundKey = ReadTempAuthKey(tempBytes);
        if (boundKey == tempAuthKeyId)
        {
            return authKeyId;
        }
        return null;
    }

    public IReadOnlyList<long> GetTempAuthKeys(long authKeyId)
    {
        _storeBound.ListDeleteByScore(DateTimeOffset.Now.ToUnixTimeMilliseconds(), authKeyId);
        var queryResult = _storeBound.ListGet(authKeyId);
        List<long> result = new List<long>();
        foreach (var v in queryResult)
        {
            result.Add(ReadTempAuthKey(v));
        }
        return result;
    }

    private static long ReadAuthKey(byte[] bytes)
    {
        var value = new TLBytes(bytes, 0, bytes.Length);
        if (value.Constructor != Constructors.baseLayer_BoundAuthKey)
            throw new InvalidDataException("Bound auth-key codec/version mismatch.");
        return ((TLBoundAuthKey)value).AsBoundAuthKey().AuthKeyId;
    }

    private static long ReadTempAuthKey(byte[] bytes)
    {
        var value = new TLBytes(bytes, 0, bytes.Length);
        if (value.Constructor != Constructors.baseLayer_BoundTempAuthKey)
            throw new InvalidDataException("Bound temp-auth-key codec/version mismatch.");
        return ((TLBoundTempAuthKey)value).AsBoundTempAuthKey().TempAuthKeyId;
    }
}