67 lines
2.6 KiB
C#
67 lines
2.6 KiB
C#
using Microsoft.Data.Sqlite;
|
|
|
|
namespace MxGateway.Server.Security.Authentication;
|
|
|
|
public sealed class SqliteApiKeyStore(AuthSqliteConnectionFactory connectionFactory) : IApiKeyStore
|
|
{
|
|
public Task<ApiKeyRecord?> FindByKeyIdAsync(string keyId, CancellationToken cancellationToken)
|
|
{
|
|
return FindByKeyIdAsync(keyId, requireActive: false, cancellationToken);
|
|
}
|
|
|
|
public Task<ApiKeyRecord?> FindActiveByKeyIdAsync(string keyId, CancellationToken cancellationToken)
|
|
{
|
|
return FindByKeyIdAsync(keyId, requireActive: true, cancellationToken);
|
|
}
|
|
|
|
public async Task MarkKeyUsedAsync(string keyId, DateTimeOffset usedUtc, CancellationToken cancellationToken)
|
|
{
|
|
await using SqliteConnection connection = connectionFactory.CreateConnection();
|
|
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
|
|
|
await using SqliteCommand command = connection.CreateCommand();
|
|
command.CommandText = """
|
|
UPDATE api_keys
|
|
SET last_used_utc = $last_used_utc
|
|
WHERE key_id = $key_id AND revoked_utc IS NULL;
|
|
""";
|
|
command.Parameters.AddWithValue("$key_id", keyId);
|
|
command.Parameters.AddWithValue("$last_used_utc", usedUtc.ToString("O"));
|
|
|
|
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
private async Task<ApiKeyRecord?> FindByKeyIdAsync(
|
|
string keyId,
|
|
bool requireActive,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
await using SqliteConnection connection = connectionFactory.CreateConnection();
|
|
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
|
|
|
await using SqliteCommand command = connection.CreateCommand();
|
|
command.CommandText = requireActive
|
|
? """
|
|
SELECT key_id, key_prefix, secret_hash, display_name, scopes, created_utc, last_used_utc, revoked_utc
|
|
FROM api_keys
|
|
WHERE key_id = $key_id AND revoked_utc IS NULL;
|
|
"""
|
|
: """
|
|
SELECT key_id, key_prefix, secret_hash, display_name, scopes, created_utc, last_used_utc, revoked_utc
|
|
FROM api_keys
|
|
WHERE key_id = $key_id;
|
|
""";
|
|
command.Parameters.AddWithValue("$key_id", keyId);
|
|
|
|
await using SqliteDataReader reader = await command.ExecuteReaderAsync(cancellationToken)
|
|
.ConfigureAwait(false);
|
|
|
|
if (!await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ApiKeyRecordReader.Read(reader);
|
|
}
|
|
}
|