Exemple #1
0
        private static void TryAddDefaultPolicy(this IServiceCollection services, ISafeLogger logger,
                                                AuthorizationOptions x, string scheme)
        {
            if (x.DefaultPolicy?.AuthenticationSchemes.Count != 0)
            {
                logger?.Info(() =>
                             $"Skipping default policy build; '{string.Join(",", x.DefaultPolicy?.AuthenticationSchemes ?? Enumerable.Empty<string>())}' already registered.");
                return;
            }

            logger?.Info(() => $"Registering default policy with scheme '{scheme}'.");
            x.DefaultPolicy = new AuthorizationPolicyBuilder(scheme)
                              .RequireAuthenticatedUserExtended(services)
                              .Build();
        }
Exemple #2
0
        public void AddCloudMetricsPublisher(IMetricsBuilder builder, ISafeLogger logger, AzureOptions options)
        {
            logger.Info(() => "Adding Application Insights Metrics & Health Checks Reporting");

            builder.PushToApplicationInsights(p =>
            {
                p.MetricsSampleEventName = Constants.Events.MetricsSample;
                p.HealthCheckEventName   = Constants.Events.HealthCheck;
                p.PublishHealthChecks    = true;
                p.PublishHealthy         = false;
                p.PublishMetrics         = true;
            });
        }
Exemple #3
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            if (!_options.CurrentValue.Enabled)
            {
                return;
            }

            _logger.Info(() => "Starting schema discovery...");

            var schemaRelativeDir = _options.CurrentValue.SchemaFolder;

            if (!string.IsNullOrWhiteSpace(schemaRelativeDir))
            {
                if (schemaRelativeDir.StartsWith("/") || schemaRelativeDir.StartsWith("\\"))
                {
                    schemaRelativeDir = schemaRelativeDir.Substring(1);
                }

                var schemaDir = Path.Combine(_environment.ContentRootPath, schemaRelativeDir);
                if (Directory.Exists(schemaDir))
                {
                    _logger.Info(() => "Found schemas in {SchemaDir}", schemaDir);

                    var revision = await UpdateSchemaAsync(schemaRelativeDir,
                                                           _options.CurrentValue.ApplicationId ?? Constants.Schemas.DefaultApplicationId);

                    if (revision != 0)
                    {
                        _logger.Info(() => "Schema updated to revision {Revision}", revision);
                    }
                    else
                    {
                        _logger.Info(() => "Schema is unchanged");
                    }
                }
            }
        }
Exemple #4
0
        private static void ScanForGeneratedObjects(this IServiceCollection services, string backendType,
                                                    IConfiguration security, ISafeLogger logger, string rootPath, Assembly assembly)
        {
            foreach (var type in assembly.GetExportedTypes())
            {
                if (!type.IsAbstract || !type.IsSealed)
                {
                    continue;
                }

                if (type.Name != "ServiceCollectionExtensions")
                {
                    continue;
                }

                var method = type.GetMethod("AddGenerated",
                                            new[] { typeof(IServiceCollection), typeof(IConfiguration), typeof(string) });
                if (method == null)
                {
                    continue;
                }

                Type batchOptionsType;
                switch (backendType)
                {
                case nameof(DocumentDb):
                    batchOptionsType = typeof(DocumentDbBatchOptions);
                    break;

                case nameof(SqlServer):
                    batchOptionsType = typeof(SqlServerBatchOptions);
                    break;

                case nameof(Sqlite):
                    batchOptionsType = typeof(SqliteBatchOptions);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                logger.Info(() => "Found generated objects API in {AssemblyName}", assembly.GetName().Name);
                method.MakeGenericMethod(batchOptionsType)
                .Invoke(null, new object[] { services, security, rootPath });
            }
        }
Exemple #5
0
 private void OnSettingsChanged(BackgroundTaskOptions changed)
 {
     _logger.Info(() => "Background task options changed, recycling the host.");
     Stop();
     Start();
 }
Exemple #6
0
        public static IServiceCollection AddHq(this IServiceCollection services, IWebHostEnvironment env,
                                               IConfiguration config, ISafeLogger logger)
        {
            var subject = Assembly.GetCallingAssembly();

            if (!(config is IConfigurationRoot configRoot))
            {
                throw new ArgumentException("HQ requires access to the root configuration.", nameof(config));
            }

            services.TryAddSingleton(configRoot);
            services.TryAddSingleton(services);

            var hq = configRoot.GetSection("HQ");

            //
            // Core Services:
            services.AddTypeResolver();
            services.AddLocalTimestamps();
            services.AddSafeLogging();
            services.AddValidOptions();
            services.AddTraceContext();

            //
            // Platform Services:
            services.AddSecurityPolicies(hq.GetSection("Security"), hq.GetSection("SuperUser"), logger);
            services.AddVersioning(hq.GetSection("Versioning"));
            services.AddMultiTenancy <IdentityTenant, IdentityApplication>(hq.GetSection("MultiTenancy"))
            .AddIdentityTenantContextStore <IdentityTenant>()
            .AddIdentityApplicationContextStore <IdentityApplication>();

            //
            // Platform APIs:
            services
            .AddOperationsApi(hq.GetSection("Ops"))
            .AddPlatformApi(hq.GetSection("Api"))
            .AddBackgroundTasksApi(hq.GetSection("BackgroundTasks"))
            .AddConfigurationApi(configRoot, hq.GetSection("Configuration"))
            .AddIdentityApi(hq.GetSection("IdentityApi"))
            .AddSchemaApi(hq.GetSection("Schema"))
            .AddMetaApi(hq.GetSection("Meta"));

            var tasksBuilder    = services.AddBackgroundTasks(hq.GetSection("BackgroundTasks"));
            var identityBuilder = services.AddIdentityExtended(hq.GetSection("Identity"));
            var runtimeBuilder  = services.AddRuntimeApi(hq.GetSection("Runtime"));
            var schemaBuilder   = services.AddSchemaDiscovery(hq.GetSection("Schema"));

            //
            // Cloud:
            var cloud = configRoot.GetSection("Cloud");

            switch (cloud["Provider"])
            {
            case nameof(Azure):
            {
                var options = new AzureOptions();
                cloud.FastBind(options);
                services.AddCloudServices(logger, options);
                break;
            }
            }

            //
            // Backend Services:
            var backend  = configRoot.GetSection("Backend");
            var dbConfig = backend.GetSection("DbOptions");

            if (dbConfig?.Value == null)
            {
                dbConfig = null;
            }

            var backendType = backend["Type"];

            if (string.IsNullOrWhiteSpace(backendType))
            {
                logger.Warn(() => "No backend type found!");
            }
            else
            {
                logger.Info(() => "Installing {BackendType} back-end services.", backendType);
            }

            switch (backendType)
            {
            case nameof(DocumentDb):
                tasksBuilder.AddDocumentDbBackgroundTaskStore(backend.GetConnectionString("Tasks"));
                identityBuilder.AddDocumentDbIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity"));
                runtimeBuilder.AddDocumentDbRuntimeStores(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig);
                schemaBuilder.AddDocumentDbSchemaStores(backend.GetConnectionString("Schema"));
                break;

            case nameof(SqlServer):
                tasksBuilder.AddSqlServerBackgroundTasksStore(backend.GetConnectionString("Tasks"), r => r.GetRequiredService <IServerTimestampService>().GetCurrentTime());
                identityBuilder.AddSqlServerIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity"), ConnectionScope.ByRequest, dbConfig);
                runtimeBuilder.AddSqlServerRuntime(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig);
                schemaBuilder.AddSqlServerSchemaStores();
                break;

            case nameof(Sqlite):
                tasksBuilder.AddSqliteBackgroundTasksStore(backend.GetConnectionString("Tasks"));
                identityBuilder.AddSqliteIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity"), ConnectionScope.ByRequest, dbConfig);
                runtimeBuilder.AddSqliteRuntime(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig);
                schemaBuilder.AddSqliteSchemaStores();
                break;

            default:
                throw new ArgumentOutOfRangeException(backendType, typeof(string), null);
            }

            //
            // Runtime Services:
            {
                var runtimeOptions = new RuntimeOptions();
                hq.GetSection("Runtime").FastBind(runtimeOptions);

                if (runtimeOptions.EnableRest)
                {
                    services.AddRestRuntime();
                    logger.Info(() => "REST is enabled.");
                }

                if (runtimeOptions.EnableGraphQl)
                {
                    services.AddGraphQlRuntime();
                    logger.Info(() => "GraphQL is enabled.");
                }
            }

            //
            // Notification Services:
            services.AddEmailNotifications(hq.GetSection("Email"));

            //
            // Media Services:

            //
            // Custom Objects:
            services.ScanForGeneratedObjects(backendType, hq.GetSection("Security"), logger, "/api", subject);

            return(services);
        }
Exemple #7
0
 public void AddCloudTelemetry(IServiceCollection services, ISafeLogger logger, AzureOptions options)
 {
     logger.Info(() => "Adding Application Insights Telemetry");
     services.AddApplicationInsightsTelemetry(options.ApplicationInsights);
 }