53 lines
2.0 KiB
C#
53 lines
2.0 KiB
C#
using Host.Application.Stories;
|
|
using Knot.Shared.Kernel;
|
|
using Knot.Shared.Kernel.Configuration;
|
|
using Knot.Shared.Kernel.Constants;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MediatR;
|
|
|
|
namespace Host.Application.Federation.Commands;
|
|
|
|
public record HandshakeRequest(string Domain, string PublicKey);
|
|
public record HandshakeResponse(string Domain, string PublicKey, string Status);
|
|
|
|
public record HandshakeFederationCommand(HandshakeRequest Request) : ICommand<HandshakeResponse>;
|
|
|
|
internal sealed class HandshakeFederationCommandHandler : ICommandHandler<HandshakeFederationCommand, HandshakeResponse>
|
|
{
|
|
private readonly ISettingsService _settings;
|
|
|
|
public HandshakeFederationCommandHandler(ISettingsService settings)
|
|
{
|
|
_settings = settings;
|
|
}
|
|
|
|
public Task<Result<HandshakeResponse>> Handle(HandshakeFederationCommand request, CancellationToken cancellationToken)
|
|
{
|
|
var conf = _settings.Current;
|
|
if (!conf.EnableConfederation)
|
|
return Task.FromResult(Result.Failure<HandshakeResponse>(new Error(Errors.DisabledByAdmin, "Federation is disabled")));
|
|
|
|
if (string.IsNullOrEmpty(request.Request.Domain) || string.IsNullOrEmpty(request.Request.PublicKey))
|
|
return Task.FromResult(Result.Failure<HandshakeResponse>(DomainErrors.RequestInvalid));
|
|
|
|
var allowedList = conf.AllowedDomains?.Select(d => d.Trim().ToLower()).ToList() ?? new System.Collections.Generic.List<string>();
|
|
if (!allowedList.Contains(request.Request.Domain.ToLowerInvariant()))
|
|
return Task.FromResult(Result.Failure<HandshakeResponse>(StoryErrors.Unauthorized));
|
|
|
|
using var rsa = RSA.Create(2048);
|
|
var selfPublicKey = Convert.ToBase64String(rsa.ExportRSAPublicKey());
|
|
|
|
var response = new HandshakeResponse(
|
|
Environment.GetEnvironmentVariable("DOMAIN") ?? "knot.local",
|
|
selfPublicKey,
|
|
"Accepted"
|
|
);
|
|
|
|
return Task.FromResult(Result.Success(response));
|
|
}
|
|
}
|