Пример #1
0
        public void ConfigureServices(IServiceCollection services)
        {
            var userName = Configuration["Config:EventstoreUsername"];
            var password = Configuration["Config:EventstorePassword"];
            var host     = Configuration["Config:EventstoreSingleNodeHost"];
            var port     = Configuration["Config:EventstoreSingleNodePort"];
            var mongoConnectionString = Configuration["Config:MongoDbConnectionString"];

            if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(host) ||
                string.IsNullOrWhiteSpace(port) || string.IsNullOrWhiteSpace(mongoConnectionString))
            {
                throw new Exception("A configuration value is missing, check the configuration.");
            }

            var userCredentials = new UserCredentials(userName,
                                                      password);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddSingleton <IAccountsRepository, AccountsRepository>();
            services.AddSingleton <ITaxLedgerRepository, TaxLedgerRepository>();
            services.AddSingleton <IFeeLedgerRepository, FeeLedgerRepository>();
            services.AddTransient(s => userCredentials);

            if (_environment.IsProduction())
            {
                services.AddSingleton(f =>
                {
                    var conn = EventStoreConnection.Create(
                        ConnectionSettings.Create()
                        .SetDefaultUserCredentials(userCredentials)
                        .KeepReconnecting().KeepRetrying(),
                        ClusterSettings.Create().DiscoverClusterViaGossipSeeds().SetGossipSeedEndPoints(new[]
                    {
                        new IPEndPoint(IPAddress.Parse("52.151.78.42"), 2113),
                        new IPEndPoint(IPAddress.Parse("52.151.79.84"), 2113),
                        new IPEndPoint(IPAddress.Parse("51.140.14.214"), 2113)
                    })
                        .SetGossipTimeout(TimeSpan.FromMilliseconds(500)).Build(), "TransactionService");

                    conn.ConnectAsync().Wait();
                    return(conn);
                });
            }
            else
            {
                services.AddSingleton(f =>
                {
                    var conn = EventStoreConnection.Create(
                        ConnectionSettings.Create()
                        .SetDefaultUserCredentials(userCredentials)
                        .KeepReconnecting()
                        .KeepRetrying().UseConsoleLogger().Build(),
                        new Uri(
                            $"tcp://{userName}:{password}@{host}:{port}"));
                    conn.ConnectAsync().Wait();
                    return(conn);
                });

                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new Info {
                        Title = "TransactionService API", Version = "v1"
                    });
                });
            }


            services.AddTransient <IMongoDatabase>(s =>
            {
                var conventionPack = new ConventionPack
                {
                    new CamelCaseElementNameConvention(), new EnumRepresentationConvention(BsonType.String)
                };
                ConventionRegistry.Register("default", conventionPack, t => true);
                var url    = new MongoUrl(mongoConnectionString);
                var client = new MongoClient(url);
                return(client.GetDatabase("transactions"));
            }
                                                   );


            services.AddSingleton <IHostedService, ReadModelComposerBackgroundService>();
        }
Пример #2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //0. HTTPS en JSON options
            services.AddMvc(options =>
            {
                if (!_env.IsProduction())
                {
                    options.SslPort = 44343;
                    //in productie wordt een real SSL toegepast.
                    //default poort voor SSL 443xx (cfr. 80xx voor HTTP)
                    //gebruik van development poort 44343 (Chrome test)
                }
                //Filters zijn middleware die door alle controllers verwerkt worden.
                //HTTPS (of SSL) opleggen gebeurt met een Filter.
                //Het SSL filter veroorzaakt een redirect naar het HTTPS adres( met poortnummer 443..)
                options.Filters.Add(new RequireHttpsAttribute());
            });

            services.AddIdentity <CinemaUser, IdentityRole>()
            .AddEntityFrameworkStores <DBContext>()
            .AddDefaultTokenProviders();

            services.AddMvc(options => options.EnableEndpointRouting = false)
            .AddNewtonsoftJson(options => {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                //circulaire referenties verhinderen
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            });

            //1.Container voor DbContext en SQLrepos
            services.AddDbContext <DBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Connectionstring")), ServiceLifetime.Transient);
            services.AddScoped(typeof(IGenericRepo <>), typeof(GenericRepo <>));
            services.AddScoped(typeof(IMovieRepo), typeof(MovieRepo));
            services.AddScoped(typeof(IUserRepo), typeof(UserRepo));
            services.AddScoped(typeof(IMovieRoomRepo), typeof(MovieRoomRepo));

            //2. Services toevoegen

            //2.2 Cors
            services.AddCors(cfg =>
            {
                cfg.AddPolicy("MAGI", builder =>
                {
                    builder.AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials()
                    //.AllowAnyOrigin();
                    .WithOrigins("https://localhost:44346/", "https://fullstackcinemaapiservice.azurewebsites.net/", "http://localhost:8080", "http://localhost:5000", "http://localhost/127.0.0.1", "localhost/127.0.0.1");
                });
            });

            //2.3 Swagger
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "Cinema_Api", Version = "v1"
                });
            });


            //2.4 Automapper volgens configuratie
            var mappingConfig = new MapperConfiguration(mc =>
            {
                mc.AddProfile(new MovieProfile());
            });
            IMapper mapper = mappingConfig.CreateMapper();

            services.AddSingleton(mapper);


            //2.5 Rate limiting
            //opzetten van MemoryCache om rates te bewaren
            services.AddMemoryCache();

            //één of meerdere RateLimitRules definiëren in appSettings.json
            services.Configure <IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));

            //Singletons voor stokeren vd waarden
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton <IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
            services.AddSingleton <IIpPolicyStore, MemoryCacheIpPolicyStore>();
            services.AddSingleton <IRateLimitConfiguration, RateLimitConfiguration>();
            services.AddTransient <Seeder>();

            //2.6 Versioning
            services.AddApiVersioning(
                options =>
            {
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                // options.Conventions.Controller<RecipesController>().HasApiVersion(1, 0);
                //options.ApiVersionReader = new HeaderApiVersionReader("ver");
            });

            //2.7 Add Authentication
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    ValidateLifetime         = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer   = Configuration["Tokens:Issuer"],
                    ValidAudience = Configuration["Tokens:Audience"],

                    IssuerSigningKey = new SymmetricSecurityKey
                                           (Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
                };
                options.SaveToken = false;
            });

            //2.8 realtime
            services.AddSignalR();

            //2.9 Logger
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Warning()
                         .WriteTo.RollingFile("Serilogs/DBFirst-{Date}.txt")
                         .CreateLogger();
        }
Пример #3
0
        public static IServiceCollection RegisterLeafServices(
            this IServiceCollection services,
            Microsoft.AspNetCore.Hosting.IHostingEnvironment environment)
        {
            services.AddHttpContextAccessor();

            services.AddScoped <IUserContext, HttpUserContext>();
            services.AddTransient <UserContextLoggingMiddleware>();
            services.AddTransient <RejectIdentifiedFederationMiddleware>();

            services.AddScoped <IServerContext, HttpServerContext>();

            services.AddHttpClient <IREDCapExportService, REDCapExportService>(client =>
            {
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                client.DefaultRequestHeaders.Add("Connection", "keep-alive");
            });

            services.AddIAMServices();

            services.AddTransient <INetworkValidator, NetworkValidator>();

            services.AddTransient <IPanelConverter, PanelConverter>();

            services.AddTransient <ISqlCompiler, SqlServerCompiler>();

            services.AddTransient <IPanelValidator, SqlServerPanelValidator>();

            services.AddTransient <INetworkEndpointService, NetworkEndpointService>();

            services.AddNetworkCache();

            services.AddSingleton <NetworkEndpointConcurrentQueueSet>();

            services.AddTransient <IJwtKeyResolver, JwtKeyResolver>();

            services.AddHttpClient <INetworkEndpointRefresher, NetworkEndpointRefresher>(client =>
            {
                client.DefaultRequestHeaders.Add("Accept", @"application/json");
            });

            if (environment.IsProduction())
            {
                services.AddHostedService <BackgroundCertificateSynchronizer>();
            }

            services.AddTransient <IConceptHintSearchService, ConceptHintSearchService>();

            services.AddTransient <IConceptTreeReader, ConceptTreeReader>();

            services.AddTransient <IPreflightConceptReader, PreflightResourceReader>();
            services.AddTransient <IPreflightResourceReader, PreflightResourceReader>();

            services.AddTransient <IPatientCohortService, CtePatientCohortService>();

            services.AddSingleton <PatientCountAggregator>();

            services.AddTransient <ICohortCacheService, CohortCacheService>();

            services.AddTransient <IDemographicSqlCompiler, DemographicSqlCompiler>();
            services.AddTransient <IDemographicQueryService, DemographicQueryService>();
            services.AddTransient <IDemographicService, DemographicService>();

            services.AddTransient <IDatasetSqlCompiler, DatasetSqlCompiler>();
            services.AddTransient <IDatasetQueryService, DatasetQueryService>();
            services.AddTransient <IDatasetService, DatasetService>();

            services.AddTransient <IQueryService, QueryService>();

            services.AddAdminServices();
            services.AddModel();

            return(services);
        }
Пример #4
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            ValidateConfiguration(Configuration);

            var userName = Configuration["Config:EventstoreUsername"];
            var password = Configuration["Config:EventstorePassword"];
            var host     = Configuration["Config:EventstoreSingleNodeHost"];
            var port     = Configuration["Config:EventstoreSingleNodePort"];
            var mongoConnectionString = Configuration["Config:MongoDbConnectionString"];

            var userCredentials = new UserCredentials(userName,
                                                      password);

            services.AddSingleton(Configuration);

            if (_environment.IsProduction())
            {
                services.AddSingleton(f =>
                {
                    var conn = EventStoreConnection.Create(
                        ConnectionSettings.Create()
                        .SetDefaultUserCredentials(userCredentials)
                        .KeepReconnecting(),
                        ClusterSettings.Create().DiscoverClusterViaGossipSeeds().SetGossipSeedEndPoints(new[]
                    {
                        new IPEndPoint(IPAddress.Parse("52.151.78.42"), 2113),
                        new IPEndPoint(IPAddress.Parse("52.151.79.84"), 2113),
                        new IPEndPoint(IPAddress.Parse("51.140.14.214"), 2113)
                    })
                        .SetGossipTimeout(TimeSpan.FromMilliseconds(500)).Build(), "TransactionService");

                    conn.ConnectAsync().Wait();
                    return(conn);
                });
            }
            else
            {
                services.AddSingleton(f =>
                {
                    var conn = EventStoreConnection.Create(
                        ConnectionSettings.Create()
                        .SetDefaultUserCredentials(userCredentials)
                        .KeepReconnecting(),
                        new Uri(
                            $"tcp://{userName}:{password}@{host}:{port}"));
                    conn.ConnectAsync().Wait();
                    return(conn);
                });
            }

            services.AddTransient <IMongoDatabase>(s =>
            {
                var conventionPack = new ConventionPack
                {
                    new CamelCaseElementNameConvention(), new EnumRepresentationConvention(BsonType.String)
                };
                ConventionRegistry.Register("default", conventionPack, t => true);
                var url    = new MongoUrl(mongoConnectionString);
                var client = new MongoClient(url);
                return(client.GetDatabase("transactions"));
            }
                                                   );


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddHangfire(g =>
            {
                g.UseMongoStorage(mongoConnectionString, "hangfire");
            });

            services.AddHostedService <TransactionRequestListener>();
        }
Пример #5
0
        public static IServiceCollection RegisterLeafServices(
            this IServiceCollection services,
            Microsoft.AspNetCore.Hosting.IHostingEnvironment environment)
        {
            services.AddHttpContextAccessor();

            services.AddScoped <IUserContext, HttpUserContext>();
            services.AddTransient <UserContextLoggingMiddleware>();
            services.AddTransient <RejectInvalidFederatedUserMiddleware>();

            services.AddScoped <IServerContext, HttpServerContext>();

            services.AddHttpClient <IREDCapExportService, REDCapExportService>(client =>
            {
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                client.DefaultRequestHeaders.Add("Connection", "keep-alive");
            });

            services.AddIAMServices();

            services.AddTransient <ISqlCompiler, SqlServerCompiler>();

            services.AddTransient <NetworkEndpointProvider.INetworkEndpointReader, NetworkEndpointReader>();

            services.AddNetworkCache();

            services.AddCohortQueryExecutionService();

            services.AddSingleton <NetworkEndpointConcurrentQueueSet>();

            services.AddTransient <IJwtKeyResolver, JwtKeyResolver>();

            services.AddHttpClient <INetworkEndpointRefresher, NetworkEndpointRefresher>(client =>
            {
                client.DefaultRequestHeaders.Add("Accept", @"application/json");
            });

            if (environment.IsProduction())
            {
                services.AddHostedService <BackgroundCertificateSynchronizer>();
            }

            services.AddTransient <ConceptHintSearcher.IConceptHintSearchService, ConceptHintSearchService>();
            services.AddTransient <ConceptTreeSearcher.IConceptTreeReader, ConceptTreeReader>();
            services.AddTransient <PreflightResourceChecker.IPreflightConceptReader, PreflightResourceReader>();
            services.AddTransient <PreflightResourceChecker.IPreflightResourceReader, PreflightResourceReader>();
            services.AddTransient <CohortCounter.ICohortCacheService, CohortCacheService>();
            services.AddTransient <IDemographicSqlCompiler, DemographicSqlCompiler>();
            services.AddTransient <DemographicCompilerValidationContextProvider.ICompilerContextProvider, DemographicCompilerContextProvider>();
            services.AddTransient <DemographicProvider.IDemographicsExecutor, DemographicsExecutor>();
            services.AddTransient <IDatasetSqlCompiler, DatasetSqlCompiler>();
            services.AddTransient <DatasetCompilerValidationContextProvider.ICompilerContextProvider, DatasetCompilerContextProvider>();
            services.AddTransient <IDatasetQueryFetcher, DatasetQueryFetcher>();
            services.AddTransient <DatasetProvider.IDatasetExecutor, DatasetExecutor>();
            services.AddTransient <IQueryService, QueryService>();
            services.AddTransient <DataImporter.IImportService, ImportService>();
            services.AddTransient <DataImporter.IImportIdentifierMappingService, ImportIdentifierMappingService>();
            services.AddTransient <NotificationManager.INotificationService, SmtpService>();
            services.AddTransient <IObfuscationService, ObfuscationService>();
            services.AddTransient <IConceptDatasetSqlCompiler, ConceptDatasetSqlCompiler>();
            services.AddTransient <ConceptDatasetCompilerValidationContextProvider.ICompilerContextProvider, ConceptDatasetCompilerContextProvider>();
            services.AddTransient <IPanelDatasetSqlCompiler, PanelDatasetSqlCompiler>();
            services.AddTransient <PanelDatasetCompilerValidationContextProvider.ICompilerContextProvider, PanelDatasetCompilerContextProvider>();

            services.AddAdminServices();
            services.RegisterLeafCore();

            return(services);
        }
Пример #6
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app">The application to configure.</param>
        /// <param name="env">The environment information to use in configuration phase.</param>
        /// <param name="applicationLifetime"></param>
        public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, Microsoft.AspNetCore.Hosting.IApplicationLifetime applicationLifetime)
        {
            if (!env.IsProduction())
            {
                app.UseDeveloperExceptionPage();
            }

            //app.UseHealthChecks("/healthz");
            //app.UseMiddleware<StartupTasksMiddleware>();

            applicationLifetime.ApplicationStopping.Register(() => { });

            //This ensures (or improves chances) to flush log buffers before (a graceful) shutdown.
            //It appears there isn't other way (e.g. in Program) than taking a reference to the global
            //static Serilog instance.
            applicationLifetime.ApplicationStopped.Register(Log.CloseAndFlush);

            app.UseExceptionHandler(errorApp =>
            {
                errorApp.Run(async context =>
                {
                    var errorFeature = context.Features.Get <IExceptionHandlerFeature>();
                    var exception    = errorFeature.Error;

                    var problemDetails = new ValidationProblemDetails
                    {
                        Instance = $"urn:oneboxdeployment:error:{Guid.NewGuid()}"
                    };

                    if (exception is BadHttpRequestException badHttpRequestException)
                    {
                        problemDetails.Title  = "Invalid request";
                        problemDetails.Status = (int)typeof(BadHttpRequestException).GetProperty("StatusCode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(badHttpRequestException);
                        problemDetails.Detail = badHttpRequestException.Message;
                    }
                    else
                    {
                        problemDetails.Title  = "An unexpected error";
                        problemDetails.Status = 500;
                        problemDetails.Detail = Environment.IsDevelopment() ? exception.Demystify().ToString() : string.Empty;
                    }

                    Logger.LogInformation(Events.GlobalExceptionHandler.Id, Events.GlobalExceptionHandler.FormatString, problemDetails);

                    context.Response.StatusCode = problemDetails.Status.Value;
                    context.Response.WriteJson(problemDetails, "application/problem+json");

                    await Task.CompletedTask.ConfigureAwait(false);
                });
            });

            //Security headers will always be added and by default the disallow everything.
            //The trimming is a robustness measure to make sure the URL has one trailing slash.
            //The listening address is needed for security headers. This is the public
            //API address.
            var appsettingsSection = Configuration.GetSection("AppSettings");
            var listeningAddress   = appsettingsSection["OneBoxDeploymentApiUrl"];

            listeningAddress = (listeningAddress ?? app.ServerFeatures.Get <IServerAddressesFeature>().Addresses.FirstOrDefault()).EnsureTrailing('/');

            //Note: the constructor checks ConfigurationKeys forbidden in production are not found.
            if (!env.IsProduction())
            {
                //Creates a route to specifically throw and unhandled exception. This route is most likely injected only in testing.
                var alwaysFaultyRoute = Configuration.GetValue <string>(ConfigurationKeys.AlwaysFaultyRoute, null);
                if (alwaysFaultyRoute != null)
                {
                    app.Map(alwaysFaultyRoute, routeBuilder => routeBuilder.Run(context => throw new Exception($"Fault injected route for testing ({context.Request.PathBase}/{context.Request.PathBase}).")));
                }
            }

            Logger.LogInformation(Events.SwaggerDocumentation.Id, Events.SwaggerDocumentation.FormatString, listeningAddress + SwaggerRoot + "/");
            var defaultSecurityPolicies = new HeaderPolicyCollection()
                                          .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365)
                                          .RemoveServerHeader()
                                          .AddFrameOptionsDeny();

            app.UseSecurityHeaders(defaultSecurityPolicies);
            app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/" + SwaggerRoot), swaggerBranch =>
            {
                //See configuration at https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders.
                const string GoogleStyles   = "https://fonts.googleapis.com";
                const string GoogleFontsUrl = "https://fonts.gstatic.com";
                var clientUrl = Path.Combine(listeningAddress, SwaggerRoot).EnsureTrailing('/');
                //Additional information for the many Feature-Policy none definitions:
                //https://github.com/w3c/webappsec-feature-policy/issues/189#issuecomment-452401661.
                swaggerBranch.UseSecurityHeaders(new HeaderPolicyCollection().AddFeaturePolicy(builder =>
                {
                    builder.AddAccelerometer().None();
                    builder.AddAmbientLightSensor().None();
                    builder.AddAutoplay().None();
                    builder.AddCamera().None();
                    builder.AddEncryptedMedia().None();
                    builder.AddFullscreen().None();
                    builder.AddGeolocation().None();
                    builder.AddGyroscope().None();
                    builder.AddMagnetometer().None();
                    builder.AddMicrophone().None();
                    builder.AddMidi().None();
                    builder.AddPayment().None();
                    builder.AddPictureInPicture().None();
                    builder.AddSpeaker().None();
                    builder.AddSyncXHR().None();
                    builder.AddUsb().None();
                    builder.AddVR().None();
                })
                                                 .AddXssProtectionBlock()
                                                 .AddContentTypeOptionsNoSniff()
                                                 .AddReferrerPolicyStrictOriginWhenCrossOrigin()
                                                 .AddContentSecurityPolicy(builder =>
                {
                    builder.AddReportUri().To("/cspreport");
                    builder.AddBlockAllMixedContent();
                    builder.AddConnectSrc().Self();
                    builder.AddStyleSrc().Self().UnsafeInline().Sources.Add(GoogleStyles);
                    builder.AddFontSrc().Self().Sources.Add(GoogleFontsUrl);
                    builder.AddImgSrc().Self().Sources.Add("data:");
                    builder.AddScriptSrc().Self().UnsafeInline();
                    builder.AddObjectSrc().None();
                    builder.AddFormAction().Self();
                    builder.AddFrameAncestors().None().Sources.Add(clientUrl);
                }, asReportOnly: false));
            });

            //For further Swagger related information, see at
            //https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger.
            app.UseSwagger();
            app.UseSwagger(swagger => swagger.RouteTemplate = $"{SwaggerRoot}/{{documentName}}/swagger.json");

            if (Configuration["HideSwaggerUi"]?.Equals("true") != true)
            {
                app.UseSwaggerUI(swaggerSetup =>
                {
                    swaggerSetup.SwaggerEndpoint($"/{SwaggerRoot}/{SwaggerDocumentationBasePath}/swagger.json", SwaggerDocumentationBasePath);
                    swaggerSetup.RoutePrefix = SwaggerRoot;

                    swaggerSetup.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream($"{Assembly.GetAssembly(typeof(Startup)).GetName().Name}.wwwroot.swagger.index.html");
                });
            }

            app.UseCors("CorsPolicy");

            app.UseStaticFiles();
            app.UseMvc();
        }