up
This commit is contained in:
		@@ -0,0 +1,98 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection.Extensions;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using StellaOps.Auth.Client;
 | 
			
		||||
using StellaOps.Zastava.Core.Configuration;
 | 
			
		||||
using StellaOps.Zastava.Core.Diagnostics;
 | 
			
		||||
using StellaOps.Zastava.Core.Security;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
 | 
			
		||||
public static class ZastavaServiceCollectionExtensions
 | 
			
		||||
{
 | 
			
		||||
    public static IServiceCollection AddZastavaRuntimeCore(
 | 
			
		||||
        this IServiceCollection services,
 | 
			
		||||
        IConfiguration configuration,
 | 
			
		||||
        string componentName)
 | 
			
		||||
    {
 | 
			
		||||
        ArgumentNullException.ThrowIfNull(services);
 | 
			
		||||
        ArgumentNullException.ThrowIfNull(configuration);
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(componentName))
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentException("Component name is required.", nameof(componentName));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        services.AddOptions<ZastavaRuntimeOptions>()
 | 
			
		||||
            .Bind(configuration.GetSection(ZastavaRuntimeOptions.SectionName))
 | 
			
		||||
            .ValidateDataAnnotations()
 | 
			
		||||
            .Validate(static options => !string.IsNullOrWhiteSpace(options.Tenant), "Tenant is required.")
 | 
			
		||||
            .Validate(static options => !string.IsNullOrWhiteSpace(options.Environment), "Environment is required.")
 | 
			
		||||
            .PostConfigure(options =>
 | 
			
		||||
            {
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(options.Component))
 | 
			
		||||
                {
 | 
			
		||||
                    options.Component = componentName;
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .ValidateOnStart();
 | 
			
		||||
 | 
			
		||||
        services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<LoggerFactoryOptions>, ZastavaLoggerFactoryOptionsConfigurator>());
 | 
			
		||||
        services.TryAddSingleton<IZastavaLogScopeBuilder, ZastavaLogScopeBuilder>();
 | 
			
		||||
        services.TryAddSingleton<IZastavaRuntimeMetrics, ZastavaRuntimeMetrics>();
 | 
			
		||||
        ConfigureAuthorityServices(services, configuration);
 | 
			
		||||
        services.TryAddSingleton<IZastavaAuthorityTokenProvider, ZastavaAuthorityTokenProvider>();
 | 
			
		||||
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void ConfigureAuthorityServices(IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        var authoritySection = configuration.GetSection($"{ZastavaRuntimeOptions.SectionName}:authority");
 | 
			
		||||
        var authorityOptions = new ZastavaAuthorityOptions();
 | 
			
		||||
        authoritySection.Bind(authorityOptions);
 | 
			
		||||
 | 
			
		||||
        services.AddStellaOpsAuthClient(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.Authority = authorityOptions.Issuer.ToString();
 | 
			
		||||
            options.ClientId = authorityOptions.ClientId;
 | 
			
		||||
            options.ClientSecret = authorityOptions.ClientSecret;
 | 
			
		||||
            options.AllowOfflineCacheFallback = authorityOptions.AllowStaticTokenFallback;
 | 
			
		||||
            options.ExpirationSkew = TimeSpan.FromSeconds(Math.Clamp(authorityOptions.RefreshSkewSeconds, 0, 300));
 | 
			
		||||
 | 
			
		||||
            options.DefaultScopes.Clear();
 | 
			
		||||
            var normalized = new SortedSet<string>(StringComparer.Ordinal);
 | 
			
		||||
 | 
			
		||||
            if (authorityOptions.Audience is not null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var audience in authorityOptions.Audience)
 | 
			
		||||
                {
 | 
			
		||||
                    if (string.IsNullOrWhiteSpace(audience))
 | 
			
		||||
                    {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    normalized.Add($"aud:{audience.Trim().ToLowerInvariant()}");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (authorityOptions.Scopes is not null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var scope in authorityOptions.Scopes)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(scope))
 | 
			
		||||
                    {
 | 
			
		||||
                        normalized.Add(scope.Trim());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var scope in normalized)
 | 
			
		||||
            {
 | 
			
		||||
                options.DefaultScopes.Add(scope);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user