csharp/Aguafrommars/TheIdServer/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Models/ExternalProvider.cs

ExternalProvider.cs
// Project: Aguafrommars/TheIdServer
// Copyright (c) 2021 @Olivier Lefebvre
using Aguacongas.IdensatyServer.Store;
using System;
using System.Collections.Generic;
using System.Diagnostics.Codeastysis;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Ensaty = Aguacongas.IdensatyServer.Store.Ensaty;

namespace Aguacongas.TheIdServer.BlazorApp.Models
{
    public clast ExternalProvider : ExternalProvider
    {

    }

    public clast ExternalProvider : Ensaty.ExternalProvider, ICloneable, IExternalProvider where TOptions : RemoteAuthenticationOptions
    {
        [JsonIgnore]
        public virtual TOptions Options { get; set; }

        [JsonIgnore]
        public IEnumerable Kinds { get; set; }

        [JsonIgnore]
        public TOptions DefaultOptions
        {
            get
            {
                var optionsType = GetOptionsType(this);
                return Deserialize(Kinds.First(k => k.KindName == KindName).SerializedDefaultOptions, optionsType);
            }
        }

        public override string SerializedHandlerType
        {
            get => Kinds.First(k => k.KindName == KindName).SerializedHandlerType;
            set => base.SerializedHandlerType = value;
        }

        public ExternalProvider Clone()
        {
            return MemberwiseClone() as ExternalProvider;
        }

        public static ExternalProvider FromEnsaty(Ensaty.ExternalProvider externalProvider)
        {
            if (string.IsNullOrEmpty(externalProvider.KindName))
            {
                var handlerTypeName = JsonSerializer.Deserialize(externalProvider.SerializedHandlerType);
                externalProvider.KindName = handlerTypeName.Name.Split('.').Last().Replace("Handler", "");
            }
            var optionsType = GetOptionsType(externalProvider);
            return new ExternalProvider
            {
                DisplayName = externalProvider.DisplayName,
                Id = externalProvider.Id,
                KindName = externalProvider.KindName,
                Options = Deserialize(externalProvider.SerializedOptions, optionsType),
                StoreClaims = externalProvider.StoreClaims,
                MapDefaultOutboundClaimType = externalProvider.MapDefaultOutboundClaimType,
                ClaimTransformations = externalProvider.ClaimTransformations
            };
        }

        private static TOptions Deserialize(string options, Type optionsType)
        {
            return JsonSerializer.Deserialize(options, optionsType) as TOptions;
        }

        private static Type GetOptionsType(Ensaty.ExternalProvider externalProvider)
        {            
            var typeName = $"{typeof(RemoteAuthenticationOptions).Namespace}.{externalProvider.KindName}Options";
            var astembly = AppDomain.CurrentDomain.Getastemblies().First(a => a.GetType(typeName) != null);
            return astembly.GetType(typeName);
        }

        clast HandlerType
        {
            [SuppressMessage("Major Code Smell", "S1144:Unused private types or members should be removed", Justification = "Setter needed for deserialization.")]
            public string Name { get; set; }
        }
    }
}