using Microsoft.EntityFrameworkCore; using NLog.Web; using OpenIddict.Client; using OpenIddict.Validation.AspNetCore; using RobotNet.OpenIddictClient; using RobotNet.RobotManager.Data; using RobotNet.RobotManager.HubClients; using RobotNet.RobotManager.Hubs; using RobotNet.RobotManager.Services; using RobotNet.RobotManager.Services.OpenACS; using RobotNet.RobotManager.Services.Traffic; using System.Net.Http.Headers; using static OpenIddict.Abstractions.OpenIddictConstants; var builder = WebApplication.CreateBuilder(args); builder.Host.UseNLog(); //builder.AddServiceDefaults(); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddSignalR(); var openIddictOption = builder.Configuration.GetSection(nameof(OpenIddictClientProviderOptions)).Get() ?? throw new InvalidOperationException("OpenID configuration not found or invalid format."); builder.Services.AddOpenIddict() .AddValidation(options => { // Note: the validation handler uses OpenID Connect discovery // to retrieve the address of the introspection endpoint. options.SetIssuer(openIddictOption.Issuer); options.AddAudiences(openIddictOption.Audiences); // Configure the validation handler to use introspection and register the client // credentials used when communicating with the remote introspection endpoint. options.UseIntrospection() .SetClientId(openIddictOption.ClientId) .SetClientSecret(openIddictOption.ClientSecret); // Register the System.Net.Http integration. if (builder.Environment.IsDevelopment()) { options.UseSystemNetHttp(httpOptions => { httpOptions.ConfigureHttpClientHandler(context => { context.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true; }); }); } else { options.UseSystemNetHttp(); } // Register the ASP.NET Core host. options.UseAspNetCore(); }) .AddClient(options => { // Allow grant_type=client_credentials to be negotiated. options.AllowClientCredentialsFlow(); // Disable token storage, which is not necessary for non-interactive flows like // grant_type=password, grant_type=client_credentials or grant_type=refresh_token. options.DisableTokenStorage(); // Register the System.Net.Http integration and use the identity of the current // assembly as a more specific user agent, which can be useful when dealing with // providers that use the user agent as a way to throttle requests (e.g Reddit). options.UseSystemNetHttp() .SetProductInformation(typeof(Program).Assembly); var registration = new OpenIddictClientRegistration { Issuer = new Uri(openIddictOption.Issuer, UriKind.Absolute), GrantTypes = { GrantTypes.ClientCredentials }, ClientId = openIddictOption.ClientId, ClientSecret = openIddictOption.ClientSecret, }; foreach (var scope in openIddictOption.Scopes) { registration.Scopes.Add(scope); } // Add a client registration matching the client application definition in the server project. options.AddRegistration(registration); }); builder.Services.AddAuthentication(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); builder.Services.AddAuthorization(); builder.Services.AddCors(options => { options.AddDefaultPolicy(policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); }); var mapManagerOptions = builder.Configuration.GetSection("MapManager").Get() ?? throw new InvalidOperationException("OpenID configuration not found or invalid format."); //builder.Services.AddHttpContextAccessor(); builder.Services.AddSingleton(); builder.Services.AddHttpClient("MapManagerAPI", client => { client.BaseAddress = new Uri(mapManagerOptions.Url); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); }).AddHttpMessageHandler(); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); Action appDbOptions = options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("RobotNet.RobotManager")); builder.Services.AddDbContext(appDbOptions); builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(typeof(LoggerController<>)); builder.Services.AddSingleton(); builder.Services.AddHostedService(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.AddHostedService(sp => sp.GetRequiredService()); var app = builder.Build(); await app.Services.SeedRobotManagerDbAsync(); // Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapHub("/hubs/robot/online"); app.MapHub("/hubs/traffic"); app.MapHub("/hubs/robot-manager"); app.Run();