< Summary

Information
Class: Program
Assembly: LGDXRobotCloud.API
File(s): /builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Program.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 164
Coverable lines: 164
Total lines: 222
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 14
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
<Main>$(...)0%210140%

File(s)

/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Program.cs

#LineLine coverage
 1using LGDXRobotCloud.API.Authorisation;
 2using LGDXRobotCloud.API.Configurations;
 3using LGDXRobotCloud.API.Middleware;
 4using LGDXRobotCloud.API.Services;
 5using LGDXRobotCloud.API.Services.Administration;
 6using LGDXRobotCloud.API.Services.Automation;
 7using LGDXRobotCloud.API.Services.Common;
 8using LGDXRobotCloud.API.Services.Identity;
 9using LGDXRobotCloud.API.Services.Navigation;
 10using LGDXRobotCloud.Data.DbContexts;
 11using LGDXRobotCloud.Data.Entities;
 12using LGDXRobotCloud.Utilities.Constants;
 13using MassTransit;
 14using Microsoft.AspNetCore.Authentication;
 15using Microsoft.AspNetCore.Authentication.Certificate;
 16using Microsoft.AspNetCore.Authentication.JwtBearer;
 17using Microsoft.AspNetCore.Authorization;
 18using Microsoft.AspNetCore.Identity;
 19using Microsoft.AspNetCore.Server.Kestrel.Https;
 20using Microsoft.EntityFrameworkCore;
 21using Microsoft.IdentityModel.Tokens;
 22using Microsoft.OpenApi.Models;
 23using System.Security.Claims;
 24using System.Security.Cryptography.X509Certificates;
 25using System.Text;
 26
 027var builder = WebApplication.CreateBuilder(args);
 028builder.WebHost.ConfigureKestrel(cfg =>
 029{
 030  cfg.ConfigureHttpsDefaults(ctx => ctx.ClientCertificateMode = ClientCertificateMode.AllowCertificate);
 031  cfg.AddServerHeader = false;
 032});
 33
 34/*
 35 * Configuration
 36 */
 037builder.Services.Configure<LgdxRobotCloudConfiguration>(
 038  builder.Configuration.GetSection("LGDXRobotCloud")
 039);
 040builder.Services.Configure<LgdxRobotCloudSecretConfiguration>(
 041  builder.Configuration.GetSection("LGDXRobotCloudSecret")
 042);
 43
 44/*
 45 * Infrastructure
 46 */
 047builder.Services.AddMassTransit(cfg =>
 048{
 049  cfg.UsingRabbitMq((context, cfg) =>
 050  {
 051    cfg.Host(builder.Configuration["RabbitMq:Host"], builder.Configuration["RabbitMq:VirtualHost"], h =>
 052    {
 053      h.Username(builder.Configuration["RabbitMq:Username"] ?? string.Empty);
 054      h.Password(builder.Configuration["RabbitMq:Password"] ?? string.Empty);
 055    });
 056  });
 057});
 058builder.Services.AddMemoryCache();
 059builder.Services.AddControllers();
 060builder.Services.AddEndpointsApiExplorer();
 061builder.Services.AddSwaggerGen(cfg =>{
 062  cfg.SwaggerDoc("v1", new OpenApiInfo { Title = "LGDXRobot Cloud", Version = "v1" });
 063  cfg.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
 064    Description = "JWT Authorization header using the Bearer scheme.",
 065    Name = "Authorization",
 066    In = ParameterLocation.Header,
 067    Type = SecuritySchemeType.ApiKey,
 068    BearerFormat = "JWT",
 069    Scheme = "Bearer"
 070  });
 071  cfg.AddSecurityRequirement(new OpenApiSecurityRequirement
 072  {
 073    {
 074      new OpenApiSecurityScheme
 075      {
 076        Reference = new OpenApiReference
 077        {
 078          Type = ReferenceType.SecurityScheme,
 079          Id = "Bearer"
 080        }
 081      },
 082      []
 083    }
 084  });
 085});
 086builder.Services.AddGrpc(cfg => cfg.EnableDetailedErrors = true);
 087builder.Services.AddDbContextPool<LgdxContext>(cfg =>
 088  cfg.UseNpgsql(builder.Configuration["PGSQLConnectionString"])
 089  .LogTo(Console.WriteLine, LogLevel.Information)
 090  .EnableSensitiveDataLogging()
 091  .EnableDetailedErrors()
 092);
 093builder.Services.AddHttpContextAccessor();
 94
 95/*
 96 * Authentication
 97 */
 098builder.Services.AddIdentity<LgdxUser, LgdxRole>()
 099  .AddEntityFrameworkStores<LgdxContext>()
 0100  .AddTokenProvider<DataProtectorTokenProvider<LgdxUser>>(TokenOptions.DefaultProvider);
 0101builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
 0102  .AddJwtBearer(cfg =>
 0103  {
 0104    cfg.TokenValidationParameters = new TokenValidationParameters
 0105    {
 0106      ValidateIssuer = true,
 0107      ValidateAudience = true,
 0108      ValidateLifetime = true,
 0109      ValidateIssuerSigningKey = true,
 0110      ValidIssuer = builder.Configuration["LGDXRobotCloudSecret:LgdxUserJwtIssuer"],
 0111      ValidAudience = builder.Configuration["LGDXRobotCloudSecret:LgdxUserJwtIssuer"],
 0112      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["LGDXRobotCloudSecret:Lgd
 0113      ClockSkew = TimeSpan.Zero
 0114    };
 0115  });
 0116builder.Services.AddTransient<ValidateRobotClientsCertificate>();
 0117builder.Services.AddAuthentication(LgdxRobotCloudAuthenticationSchemes.RobotClientsCertificateScheme)
 0118  .AddCertificate(LgdxRobotCloudAuthenticationSchemes.RobotClientsCertificateScheme, cfg =>
 0119  {
 0120    cfg.AllowedCertificateTypes = CertificateTypes.All;
 0121    cfg.RevocationMode = X509RevocationMode.NoCheck;
 0122    cfg.Events = new CertificateAuthenticationEvents()
 0123    {
 0124      OnCertificateValidated = async ctx =>
 0125      {
 0126        string subject = ctx.ClientCertificate.Subject;
 0127        string guid = subject.Substring(subject.IndexOf("OID.0.9.2342.19200300.100.1.1=") + 30, 36);
 0128        if (guid == string.Empty)
 0129        {
 0130          ctx.Fail("Robot ID not found.");
 0131          return;
 0132        }
 0133        var validatior = ctx.HttpContext.RequestServices.GetService<ValidateRobotClientsCertificate>();
 0134        if (!await validatior!.Validate(ctx.ClientCertificate, Guid.Parse(guid)))
 0135        {
 0136          ctx.Fail("Invalid certificate / Robot not found.");
 0137          return;
 0138        }
 0139        var claims = new [] {
 0140          new Claim(ClaimTypes.NameIdentifier, guid)
 0141        };
 0142        ctx.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, ctx.Scheme.Name));
 0143        ctx.Success();
 0144      }
 0145    };
 0146  });
 0147builder.Services.AddAuthentication(LgdxRobotCloudAuthenticationSchemes.RobotClientsJwtScheme)
 0148  .AddJwtBearer(LgdxRobotCloudAuthenticationSchemes.RobotClientsJwtScheme, cfg =>
 0149  {
 0150    cfg.TokenValidationParameters = new TokenValidationParameters
 0151    {
 0152      ValidateIssuer = true,
 0153      ValidateAudience = true,
 0154      ValidateLifetime = true,
 0155      ValidateIssuerSigningKey = true,
 0156      ValidIssuer = builder.Configuration["LGDXRobotCloudSecret:RobotClientsJwtIssuer"],
 0157      ValidAudience = builder.Configuration["LGDXRobotCloudSecret:RobotClientsJwtIssuer"],
 0158      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["LGDXRobotCloudSecret:Rob
 0159      ClockSkew = TimeSpan.Zero
 0160    };
 0161  });
 0162builder.Services.AddScoped<IAuthorizationHandler, ValidateLgdxUserAccessHandler>();
 0163builder.Services.AddAuthorizationBuilder()
 0164  .AddPolicy("ValidateLgdxUserAccess", policyBuilder =>
 0165  {
 0166    policyBuilder.RequireAuthenticatedUser();
 0167    policyBuilder.AddRequirements(new ValidateLgdxUserAccessRequirement());
 0168  });
 169
 170/*
 171 * LGDX Depency Injection
 172 */
 173// Administrator
 0174builder.Services.AddScoped<IApiKeyService, ApiKeyService>();
 0175builder.Services.AddScoped<IRobotCertificateService, RobotCertificateService>();
 0176builder.Services.AddScoped<IRoleService, RoleService>();
 0177builder.Services.AddScoped<IUserService, UserService>();
 178
 179// Automation
 0180builder.Services.AddScoped<IAutoTaskService, AutoTaskService>();
 0181builder.Services.AddScoped<IFlowService, FlowService>();
 0182builder.Services.AddScoped<IProgressService, ProgressService>();
 183
 184// Identity
 0185builder.Services.AddScoped<IAuthService, AuthService>();
 0186builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
 187
 188// Automation
 0189builder.Services.AddScoped<IRealmService, RealmService>();
 0190builder.Services.AddScoped<IWaypointService, WaypointService>();
 0191builder.Services.AddScoped<IRobotService, RobotService>();
 192
 193// Custom Services
 0194builder.Services.AddScoped<ITriggerRetryService, TriggerRetryService>();
 0195builder.Services.AddScoped<ITriggerService, TriggerService>();
 0196builder.Services.AddScoped<IEmailService, EmailService>();
 0197builder.Services.AddSingleton<IEventService, EventService>();
 0198builder.Services.AddScoped<IAutoTaskSchedulerService, AutoTaskSchedulerService>();
 0199builder.Services.AddScoped<IOnlineRobotsService, OnlineRobotsService>();
 0200builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
 201
 0202var app = builder.Build();
 203
 204// Configure the HTTP request pipeline.
 0205if (app.Environment.IsDevelopment())
 0206{
 0207  app.UseSwagger();
 0208  app.UseSwaggerUI();
 0209}
 210
 0211app.UseHttpsRedirection();
 212
 0213app.UseAuthentication();
 0214app.UseAuthorization();
 215
 0216app.MapControllerRoute(
 0217  name: "Area",
 0218  pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
 0219app.MapGrpcService<RobotClientsService>();
 0220app.UseLgdxExpectionHandling();
 221
 0222app.Run();

Methods/Properties

<Main>$(System.String[])