95 lines
2.7 KiB
C#
95 lines
2.7 KiB
C#
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
|
|
namespace StellaOps.Scanner.Surface.Secrets.Providers;
|
|
|
|
internal sealed class FileSurfaceSecretProvider : ISurfaceSecretProvider
|
|
{
|
|
private readonly string _root;
|
|
|
|
public FileSurfaceSecretProvider(string root)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(root))
|
|
{
|
|
throw new ArgumentException("File secret provider root cannot be null or whitespace.", nameof(root));
|
|
}
|
|
|
|
_root = root;
|
|
}
|
|
|
|
public SurfaceSecretHandle Get(SurfaceSecretRequest request)
|
|
{
|
|
if (request is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(request));
|
|
}
|
|
|
|
var path = ResolvePath(request);
|
|
if (!File.Exists(path))
|
|
{
|
|
throw new SurfaceSecretNotFoundException(request);
|
|
}
|
|
|
|
var json = File.ReadAllText(path);
|
|
var descriptor = JsonSerializer.Deserialize<FileSecretDescriptor>(json);
|
|
if (descriptor is null)
|
|
{
|
|
throw new SurfaceSecretNotFoundException(request);
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(descriptor.Payload))
|
|
{
|
|
return SurfaceSecretHandle.Empty;
|
|
}
|
|
|
|
var bytes = Convert.FromBase64String(descriptor.Payload);
|
|
return SurfaceSecretHandle.FromBytes(bytes, descriptor.Metadata);
|
|
}
|
|
|
|
public async ValueTask<SurfaceSecretHandle> GetAsync(
|
|
SurfaceSecretRequest request,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (request is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(request));
|
|
}
|
|
|
|
var path = ResolvePath(request);
|
|
if (!File.Exists(path))
|
|
{
|
|
throw new SurfaceSecretNotFoundException(request);
|
|
}
|
|
|
|
await using var stream = File.OpenRead(path);
|
|
var descriptor = await JsonSerializer.DeserializeAsync<FileSecretDescriptor>(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
|
|
if (descriptor is null)
|
|
{
|
|
throw new SurfaceSecretNotFoundException(request);
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(descriptor.Payload))
|
|
{
|
|
return SurfaceSecretHandle.Empty;
|
|
}
|
|
|
|
var bytes = Convert.FromBase64String(descriptor.Payload);
|
|
return SurfaceSecretHandle.FromBytes(bytes, descriptor.Metadata);
|
|
}
|
|
|
|
private string ResolvePath(SurfaceSecretRequest request)
|
|
{
|
|
var name = request.Name ?? "default";
|
|
return Path.Combine(_root, request.Tenant, request.Component, request.SecretType, name + ".json");
|
|
}
|
|
|
|
private sealed class FileSecretDescriptor
|
|
{
|
|
public string? Payload { get; init; }
|
|
public Dictionary<string, string>? Metadata { get; init; }
|
|
}
|
|
}
|