Skip to content
Snippets Groups Projects
FitConnectClient.cs 6.70 KiB
using System.Net;
using Autofac;
using FitConnect.Encryption;
using FitConnect.Models;
using FitConnect.Services;
using FitConnect.Services.Interfaces;
using FitConnect.Services.Models.v1.Submission;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;

namespace FitConnect;

public abstract class FitConnectClient {
    private readonly string? _privateKeyDecryption;
    private readonly string? _privateKeySigning;
    private readonly string? _publicKeyEncryption;
    private readonly string? _publicKeySignatureVerification;
    protected readonly bool VerifiedKeysAreMandatory;


    protected FitConnectClient(FitConnectEnvironment environment,
        string clientId, string clientSecret,
        ILogger? logger = null,
        string? privateKeyDecryption = null,
        string? privateKeySigning = null,
        string? publicKeyEncryption = null,
        string? publicKeySignatureVerification = null
    ) : this() {
        _privateKeyDecryption = privateKeyDecryption;
        _privateKeySigning = privateKeySigning;
        _publicKeyEncryption = publicKeyEncryption;
        _publicKeySignatureVerification = publicKeySignatureVerification;
        OAuthService = new OAuthService(environment.TokenUrl, "V1", clientId, clientSecret, logger);
        SubmissionService =
            new SubmissionService(environment.SubmissionUrl[0], OAuthService,
                publicKeySignatureVerification == null
                    ? null
                    : new JsonWebKey(publicKeySignatureVerification),
                logger: logger);
        RouteService = new RouteService(environment.RoutingUrl, logger: logger);
        CasesService = new CasesService(environment.SubmissionUrl[0], OAuthService, logger: logger);
        DestinationService =
            new DestinationService(environment.SubmissionUrl[0], OAuthService, logger: logger);
        Logger = logger;
        VerifiedKeysAreMandatory = environment.VerifiedKeysAreMandatory;
    }

    protected FitConnectClient(FitConnectEnvironment environment,
        string clientId, string clientSecret,
        IContainer container,
        string? privateKeyDecryption = null,
        string? privateKeySigning = null,
        string? publicKeyEncryption = null,
        string? publicKeySignatureVerification = null
    ) : this() {
        _privateKeyDecryption = privateKeyDecryption;
        _privateKeySigning = privateKeySigning;
        _publicKeyEncryption = publicKeyEncryption;
        _publicKeySignatureVerification = publicKeySignatureVerification;
        OAuthService = container.Resolve<IOAuthService>();
        SubmissionService = container.Resolve<ISubmissionService>();
        RouteService = container.Resolve<IRouteService>();
        CasesService = container.Resolve<ICasesService>();
        DestinationService = container.Resolve<IDestinationService>();
        Logger = container.Resolve<ILogger>();
    }


    private FitConnectClient() {
        // Take care of OAuthService if make the constructor public
        Encryption = new FitEncryption(Logger);
    }


    public IOAuthService OAuthService { get; } =
        null!; // To resolve the warning, is only applicable for the **private** constructor

    protected ISubmissionService SubmissionService { get; } = null!;
    protected IRouteService RouteService { get; } = null!;
    protected IDestinationService DestinationService { get; } = null!;
    protected ICasesService CasesService { get; } = null!;
    protected ILogger? Logger { get; }
    protected FitEncryption Encryption { get; set; }

    public void SetProxy(WebProxy proxy) {
        OAuthService.Proxy = proxy;
        SubmissionService.Proxy = proxy;
        DestinationService.Proxy = proxy;
        RouteService.Proxy = proxy;
    }

    public WebProxy? GetProxy() {
        return OAuthService.Proxy;
    }


    /// <summary>
    ///     Retrieve the events for the submission
    /// </summary>
    /// <param name="caseId"></param>
    /// <param name="destinationId"></param>
    /// <param name="skipTest"></param>
    /// <returns></returns>
    public List<SecurityEventToken> GetStatusForSubmission(string caseId, string destinationId,
        bool skipTest = false) {
        var events = SubmissionService.GetStatusForSubmissionAsync(caseId, destinationId, skipTest)
                         .Result?.Select(e => new SecurityEventToken(e!)).ToList() ??
                     new List<SecurityEventToken>();
        return events;
    }

    /// <summary>
    ///     Retrieve the events for the submission
    /// </summary>
    /// <param name="submission"></param>
    /// <param name="skipTest"></param>
    /// <returns></returns>
    public List<SecurityEventToken> GetStatusForSubmission(SubmissionForPickupDto submission,
        bool skipTest = false) {
        if (submission?.CaseId == null || submission.DestinationId == null) {
            throw new ArgumentNullException(nameof(submission));
        }

        var events = SubmissionService
            .GetStatusForSubmissionAsync(submission.CaseId, submission.DestinationId, skipTest)
            .Result;
        return events?.Select(e => new SecurityEventToken(e)).ToList() ??
               new List<SecurityEventToken>();
    }

    /// <summary>
    ///     Encrypt attachments (Anhänge)
    /// </summary>
    /// <param name="publicKey"></param>
    /// <param name="attachment"></param>
    /// <returns></returns>
    public KeyValuePair<string, string> Encrypt(string publicKey, Attachment attachment) {
        var content = Encryption.Encrypt(attachment.Content ?? Array.Empty<byte>(), publicKey);
        return new KeyValuePair<string, string>(attachment.Id, content);
    }

    /// <summary>
    ///     Encrypt attachments (Anhänge)
    /// </summary>
    /// <param name="publicKey">Public key for encryption</param>
    /// <param name="attachments">List of attachments to encrypt</param>
    /// <returns></returns>
    public Dictionary<string, string> Encrypt(string publicKey,
        IEnumerable<Attachment> attachments) {
        return attachments.Select(a => Encrypt(publicKey, a))
            .ToDictionary(p => p.Key, p => p.Value);
    }
}

public static class FitConnectClientExtensions {
    /// <summary>
    /// </summary>
    /// <param name="host"></param>
    /// <param name="port"></param>
    /// <param name="username"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    public static T WithProxy<T>(this T caller, string host, int port, string? username = null,
        string? password = null) where T : FitConnectClient {
        var proxy = new WebProxy(host, port);
        if (username != null && password != null)
            proxy.Credentials = new NetworkCredential(username, password);

        caller.SetProxy(proxy);
        return caller;
    }
}