diff --git a/Certificates/DotNet Foundation CA.pfx b/Certificates/DotNet Foundation CA.pfx new file mode 100644 index 000000000..67ce2e415 Binary files /dev/null and b/Certificates/DotNet Foundation CA.pfx differ diff --git a/Certificates/eShopOnContainers.pfx b/Certificates/eShopOnContainers.pfx new file mode 100644 index 000000000..c5962c1c2 Binary files /dev/null and b/Certificates/eShopOnContainers.pfx differ diff --git a/docker-compose.override.yml b/docker-compose.override.yml deleted file mode 100644 index 969cfb922..000000000 --- a/docker-compose.override.yml +++ /dev/null @@ -1,317 +0,0 @@ -version: '3.4' - -# The default docker-compose.override file can use the "localhost" as the external name for testing web apps within the same dev machine. -# The ESHOP_EXTERNAL_DNS_NAME_OR_IP environment variable is taken, by default, from the ".env" file defined like: -# ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost -# but values present in the environment vars at runtime will always override those defined inside the .env file -# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance. - -services: - sql.data: - environment: - - SA_PASSWORD=Pass@word - - ACCEPT_EULA=Y - ports: - - "5433:1433" # Important: In a production environment your should remove the external port - - nosql.data: - ports: - - "27017:27017" # Important: In a production environment your should remove the external port - - basket.data: - ports: - - "6379:6379" # Important: In a production environment your should remove the external port - - rabbitmq: - ports: - - "15672:15672" # Important: In a production environment your should remove the external port - - "5672:5672" # Important: In a production environment your should remove the external port - - identity.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104 - - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback #localhost do not work for UWP login, so we have to use "external" IP always - - ConnectionString=${ESHOP_AZURE_IDENTITY_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word} - - MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 #Local: You need to open your local dev-machine firewall at range 5100-5110. - - LocationApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5109 - - MarketingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110 - - BasketApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 - - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 - - MobileShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5120 - - WebShoppingAggClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121 - - UseCustomizationData=True - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - ports: - - "5105:80" - - basket.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureServiceBusEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - - ports: - - "5103:80" # Important: In a production environment your should remove the external port (5103) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - catalog.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word} - - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://localhost:5202/api/v1/c/catalog/items/[0]/pic/} #Local: You need to open your local dev-machine firewall at range 5100-5110. - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} - - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} - - UseCustomizationData=True - - AzureServiceBusEnabled=False - - AzureStorageEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - ports: - - "5101:80" # Important: In a production environment your should remove the external port (5101) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - ordering.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - UseCustomizationData=True - - AzureServiceBusEnabled=False - - CheckUpdateTime=30000 - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - ports: - - "5102:80" # Important: In a production environment your should remove the external port (5102) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - - ordering.backgroundtasks: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - UseCustomizationData=True - - AzureServiceBusEnabled=False - - CheckUpdateTime=30000 - - GracePeriodTime=1 - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - ports: - - "5111:80" - - marketing.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word} - - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - - MongoDatabase=MarketingDb - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI} - - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING_URL:-http://localhost:5110/api/v1/campaigns/[0]/pic/} - - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME} - - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY} - - AzureServiceBusEnabled=False - - AzureStorageEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - ports: - - "5110:80" # Important: In a production environment your should remove the external port (5110) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - payment.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureServiceBusEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - ports: - - "5108:80" # Important: In a production environment your should remove the external port (5108) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - locations.api: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosql.data} - - Database=LocationsDb - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureServiceBusEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - ports: - - "5109:80" # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - mobileshoppingapigw: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5200:80" - volumes: - - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} - - mobilemarketingapigw: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5201:80" - volumes: - - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} - - webshoppingapigw: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5202:80" - volumes: - - ./src/ApiGateways/Web.Bff.Shopping/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} - - webmarketingapigw: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - IdentityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5203:80" - volumes: - - ./src/ApiGateways/Web.Bff.Marketing/apigw:${ESHOP_OCELOT_VOLUME_SPEC:-/app/configuration} - - mobileshoppingagg: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - urls__basket=http://basket.api - - urls__catalog=http://catalog.api - - urls__orders=http://ordering.api - - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5120:80" # Important: In a production environment your should remove the external port (5120) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - webshoppingagg: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - urls__basket=http://basket.api - - urls__catalog=http://catalog.api - - urls__orders=http://ordering.api - - urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5121:80" # Important: In a production environment your should remove the external port (5121) kept here for microservice debugging purposes. - # The API Gateway redirects and access through the internal port (80). - - ordering.signalrhub: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureServiceBusEnabled=False - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110. - ports: - - "5112:80" - - webstatus: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://catalog.api/hc - - OrderingUrl=http://ordering.api/hc - - OrderingBackgroundTasksUrl=http://ordering.backgroundtasks/hc - - BasketUrl=http://basket.api/hc - - IdentityUrl=http://identity.api/hc - - LocationsUrl=http://locations.api/hc - - MarketingUrl=http://marketing.api/hc - - PaymentUrl=http://payment.api/hc - - mvc=http://webmvc/hc - - spa=http://webspa/hc - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - ports: - - "5107:80" - - webspa: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. - - PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - - MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5203 - - CatalogUrlHC=http://catalog.api/hc - - OrderingUrlHC=http://ordering.api/hc - - IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - - BasketUrlHC=http://basket.api/hc - - MarketingUrlHC=http://marketing.api/hc - - PaymentUrlHC=http://payment.api/hc - - UseCustomizationData=True - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - ports: - - "5104:80" - - webmvc: - environment: - - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 - - PurchaseUrl=http://webshoppingapigw - - IdentityUrl=http://10.0.75.1:5105 # Local Mac: Use http://docker.for.mac.localhost:5105 || Local Windows: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. || #Remote access: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. - - MarketingUrl=http://webmarketingapigw - - CatalogUrlHC=http://catalog.api/hc - - OrderingUrlHC=http://ordering.api/hc - - IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser. - - BasketUrlHC=http://basket.api/hc - - MarketingUrlHC=http://marketing.api/hc - - PaymentUrlHC=http://payment.api/hc - - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - - UseCustomizationData=True - - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - - OrchestratorType=${ORCHESTRATOR_TYPE} - - UseLoadTest=${USE_LOADTEST:-False} - ports: - - "5100:80" - diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json deleted file mode 100644 index 57b5e894d..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "urls": { - "basket": "http://localhost:55105", - "catalog": "http://localhost:55101", - "orders": "http://localhost:55102", - "identity": "http://localhost:55105" - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json deleted file mode 100644 index 57b5e894d..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "urls": { - "basket": "http://localhost:55105", - "catalog": "http://localhost:55101", - "orders": "http://localhost:55102", - "identity": "http://localhost:55105" - } -} diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json deleted file mode 100644 index 4bff4d70d..000000000 --- a/src/Services/Basket/Basket.API/appsettings.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "IdentityUrl": "http://localhost:5105", - "ConnectionString": "127.0.0.1", - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Basket", - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "EventBusRetryCount": 5, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-clien-id", - "ClientSecret": "your-client-secret" - } -} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/Certificates/DotNet Foundation CA.pfx b/src/Services/Identity/Identity.API/Certificates/DotNet Foundation CA.pfx new file mode 100644 index 000000000..67ce2e415 Binary files /dev/null and b/src/Services/Identity/Identity.API/Certificates/DotNet Foundation CA.pfx differ diff --git a/src/Services/Identity/Identity.API/Certificates/eShopOnContainers.pfx b/src/Services/Identity/Identity.API/Certificates/eShopOnContainers.pfx new file mode 100644 index 000000000..c5962c1c2 Binary files /dev/null and b/src/Services/Identity/Identity.API/Certificates/eShopOnContainers.pfx differ diff --git a/src/Services/Identity/Identity.API/Dockerfile b/src/Services/Identity/Identity.API/Dockerfile deleted file mode 100644 index 3931a135b..000000000 --- a/src/Services/Identity/Identity.API/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -ARG NODE_IMAGE=node:8.11 -FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base -WORKDIR /app -EXPOSE 80 - -FROM microsoft/dotnet:2.1-sdk as dotnet-build -WORKDIR /src - -FROM ${NODE_IMAGE} as node-build -WORKDIR /web -COPY src/Services/Identity/Identity.API . -RUN npm install -g bower@1.8.4 -RUN bower install --allow-root - -FROM dotnet-build as build -WORKDIR /src/src/Services/Identity/Identity.API/wwwroot -COPY --from=node-build /web/wwwroot . -WORKDIR /src -COPY . . -WORKDIR /src/src/Services/Identity/Identity.API -RUN dotnet restore -nowarn:msb3202,nu1503 -RUN dotnet build --no-restore -c Release -o /app - -FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app - -FROM base AS final -WORKDIR /app -COPY --from=publish /app . -ENTRYPOINT ["dotnet", "Identity.API.dll"] diff --git a/src/Services/Identity/Identity.API/Startup.cs b/src/Services/Identity/Identity.API/Startup.cs deleted file mode 100644 index 255bb82b5..000000000 --- a/src/Services/Identity/Identity.API/Startup.cs +++ /dev/null @@ -1,184 +0,0 @@ -using Autofac; -using Autofac.Extensions.DependencyInjection; -using IdentityServer4.Services; -using Microsoft.ApplicationInsights.Extensibility; -using Microsoft.ApplicationInsights.ServiceFabric; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Identity; -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Identity.API.Certificates; -using Microsoft.eShopOnContainers.Services.Identity.API.Data; -using Microsoft.eShopOnContainers.Services.Identity.API.Models; -using Microsoft.eShopOnContainers.Services.Identity.API.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.HealthChecks; -using Microsoft.Extensions.Logging; -using StackExchange.Redis; -using System; -using System.Reflection; - -namespace Microsoft.eShopOnContainers.Services.Identity.API -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public IServiceProvider ConfigureServices(IServiceCollection services) - { - RegisterAppInsights(services); - - // Add framework services. - services.AddDbContext(options => - options.UseSqlServer(Configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - })); - - services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - - services.Configure(Configuration); - - services.AddMvc(); - - if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) - { - services.AddDataProtection(opts => - { - opts.ApplicationDiscriminator = "eshop.identity"; - }) - .PersistKeysToRedis(ConnectionMultiplexer.Connect(Configuration["DPConnectionString"]), "DataProtection-Keys"); - } - - services.AddHealthChecks(checks => - { - var minutes = 1; - if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed)) - { - minutes = minutesParsed; - } - checks.AddSqlCheck("Identity_Db", Configuration["ConnectionString"], TimeSpan.FromMinutes(minutes)); - }); - - services.AddTransient, EFLoginService>(); - services.AddTransient(); - - var connectionString = Configuration["ConnectionString"]; - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; - - // Adds IdentityServer - services.AddIdentityServer(x => x.IssuerUri = "null") - .AddSigningCredential(Certificate.Get()) - .AddAspNetIdentity() - .AddConfigurationStore(options => - { - options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(migrationsAssembly); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }) - .AddOperationalStore(options => - { - options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(migrationsAssembly); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }) - .Services.AddTransient(); - - var container = new ContainerBuilder(); - container.Populate(services); - - return new AutofacServiceProvider(container.Build()); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - loggerFactory.AddAzureWebAppDiagnostics(); - loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - app.UseDatabaseErrorPage(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - } - - var pathBase = Configuration["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); - app.UsePathBase(pathBase); - } - - -#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously - app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200)); -#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously - - app.UseStaticFiles(); - - - // Make work identity server redirections in Edge and lastest versions of browers. WARN: Not valid in a production environment. - app.Use(async (context, next) => - { - context.Response.Headers.Add("Content-Security-Policy", "script-src 'unsafe-inline'"); - await next(); - }); - - app.UseForwardedHeaders(); - // Adds IdentityServer - app.UseIdentityServer(); - - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); - } - - private void RegisterAppInsights(IServiceCollection services) - { - services.AddApplicationInsightsTelemetry(Configuration); - var orchestratorType = Configuration.GetValue("OrchestratorType"); - - if (orchestratorType?.ToUpper() == "K8S") - { - // Enable K8s telemetry initializer - services.EnableKubernetes(); - } - if (orchestratorType?.ToUpper() == "SF") - { - // Enable SF telemetry initializer - services.AddSingleton((serviceProvider) => - new FabricTelemetryInitializer()); - } - } - } -} diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json deleted file mode 100644 index c5a109218..000000000 --- a/src/Services/Identity/Identity.API/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;", - "IsClusterEnv": "False", - "MvcClient": "http://localhost:5100", - "SpaClient": "http://localhost:5104", - "XamarinCallback": "http://localhost:5105/xamarincallback", - "UseCustomizationData": false, - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" - } - }, - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-clien-id", - "ClientSecret": "your-client-secret" - } -} diff --git a/src/Services/Location/Locations.API/appsettings.json b/src/Services/Location/Locations.API/appsettings.json deleted file mode 100644 index cd4166bb0..000000000 --- a/src/Services/Location/Locations.API/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "ConnectionString": "mongodb://nosql.data", - "Database": "LocationsDb", - "IdentityUrl": "http://localhost:5105", - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" - } - }, - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Locations", - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "EventBusRetryCount": 5, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-clien-id", - "ClientSecret": "your-client-secret" - } -} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/appsettings.json b/src/Services/Marketing/Marketing.API/appsettings.json deleted file mode 100644 index 2af660446..000000000 --- a/src/Services/Marketing/Marketing.API/appsettings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace" - } - }, - "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word", - "MongoConnectionString": "mongodb://nosql.data", - "MongoDatabase": "MarketingDb", - "IdentityUrl": "http://localhost:5105", - "PicBaseUrl": "http://localhost:5110/api/v1/campaigns/[0]/pic/", - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Marketing", - "AzureStorageEnabled": false, - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "EventBusRetryCount": 5, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-clien-id", - "ClientSecret": "your-client-secret" - } -} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json deleted file mode 100644 index 96dd74630..000000000 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "IdentityUrl": "http://localhost:5105", - "UseCustomizationData": false, - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" - } - }, - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Ordering", - "CheckUpdateTime": "30000", - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "EventBusRetryCount": 5, - "EventBusConnection": "localhost", - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-clien-id", - "ClientSecret": "your-client-secret" - } -} diff --git a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json deleted file mode 100644 index ab02fda0f..000000000 --- a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "IdentityUrl": "http://localhost:5105", - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Trace", - "System": "Information", - "Microsoft": "Information" - } - }, - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Ordering.signalrhub", - "EventBusRetryCount": 5, - "EventBusConnection": "localhost" -} \ No newline at end of file diff --git a/src/Web/WebMVC/Certificates/DotNet Foundation CA.pfx b/src/Web/WebMVC/Certificates/DotNet Foundation CA.pfx new file mode 100644 index 000000000..67ce2e415 Binary files /dev/null and b/src/Web/WebMVC/Certificates/DotNet Foundation CA.pfx differ diff --git a/src/Web/WebMVC/Certificates/eShopOnContainers.pfx b/src/Web/WebMVC/Certificates/eShopOnContainers.pfx new file mode 100644 index 000000000..c5962c1c2 Binary files /dev/null and b/src/Web/WebMVC/Certificates/eShopOnContainers.pfx differ diff --git a/src/Web/WebMVC/Controllers/HomeController.cs b/src/Web/WebMVC/Controllers/HomeController.cs new file mode 100644 index 000000000..24a6346ec --- /dev/null +++ b/src/Web/WebMVC/Controllers/HomeController.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace WebMVC.Controllers +{ + public class HomeController : Controller + { + public IActionResult Privacy() + { + return View(); + } + } +} \ No newline at end of file diff --git a/src/Web/WebMVC/Dockerfile b/src/Web/WebMVC/Dockerfile deleted file mode 100644 index 9847ad772..000000000 --- a/src/Web/WebMVC/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -ARG NODE_IMAGE=node:8.11 -FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base -WORKDIR /app -EXPOSE 80 - -FROM microsoft/dotnet:2.1-sdk as dotnet-build -WORKDIR /src - -FROM ${NODE_IMAGE} as node-build -WORKDIR /web -COPY src/Web/WebMVC . -RUN npm install -g bower@1.8.4 -RUN bower install --allow-root - -FROM dotnet-build as build -WORKDIR /src/src/Web/WebMVC/wwwroot -COPY --from=node-build /web/wwwroot . -WORKDIR /src -COPY . . -WORKDIR /src/src/Web/WebMVC -RUN dotnet restore -nowarn:msb3202,nu1503 - -FROM build AS publish -RUN dotnet publish --no-restore -c Release -o /app - -FROM base AS final -WORKDIR /app -COPY --from=publish /app . -ENTRYPOINT ["dotnet", "WebMVC.dll"] diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index 9c1c0a3b8..791ff0336 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -24,258 +24,274 @@ using WebMVC.Services; namespace Microsoft.eShopOnContainers.WebMVC { - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the IoC container. - public void ConfigureServices(IServiceCollection services) - { - services.AddAppInsight(Configuration) - .AddHealthChecks(Configuration) - .AddCustomMvc(Configuration) - .AddHttpClientServices(Configuration) - //.AddHttpClientLogging(Configuration) //Opt-in HttpClientLogging config - .AddCustomAuthentication(Configuration); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - - loggerFactory.AddAzureWebAppDiagnostics(); - loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - } - - var pathBase = Configuration["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); - app.UsePathBase(pathBase); - } - + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the IoC container. + public void ConfigureServices(IServiceCollection services) + { + services.Configure(opts => + { + opts.CheckConsentNeeded = context => true; + opts.MinimumSameSitePolicy = SameSiteMode.None; + }); + services.AddHttpsRedirection(opts=> + { + opts.HttpsPort = 4100; + }); + services.AddAppInsight(Configuration) + .AddHealthChecks(Configuration) + .AddCustomMvc(Configuration) + .AddHttpClientServices(Configuration) + //.AddHttpClientLogging(Configuration) //Opt-in HttpClientLogging config + .AddCustomAuthentication(Configuration); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + + loggerFactory.AddAzureWebAppDiagnostics(); + loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Error"); + app.UseHsts(); + } + + var pathBase = Configuration["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) + { + loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'"); + app.UsePathBase(pathBase); + } + + app.UseHttpsRedirection(); + app.UseCookiePolicy(); #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously - app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200)); + app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200)); #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously - app.UseSession(); - app.UseStaticFiles(); - - if (Configuration.GetValue("UseLoadTest")) - { - app.UseMiddleware(); - } - - app.UseAuthentication(); - - var log = loggerFactory.CreateLogger("identity"); - - WebContextSeed.Seed(app, env, loggerFactory); - - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Catalog}/{action=Index}/{id?}"); - - routes.MapRoute( - name: "defaultError", - template: "{controller=Error}/{action=Error}"); - }); - } - } - - static class ServiceCollectionExtensions - { - - public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) - { - services.AddApplicationInsightsTelemetry(configuration); - var orchestratorType = configuration.GetValue("OrchestratorType"); - - if (orchestratorType?.ToUpper() == "K8S") - { - // Enable K8s telemetry initializer - services.EnableKubernetes(); - } - - if (orchestratorType?.ToUpper() == "SF") - { - // Enable SF telemetry initializer - services.AddSingleton((serviceProvider) => - new FabricTelemetryInitializer()); - } - - return services; - } - - public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) - { - services.AddHealthChecks(checks => - { - var minutes = 1; - if (int.TryParse(configuration["HealthCheck:Timeout"], out var minutesParsed)) - { - minutes = minutesParsed; - } - - checks.AddUrlCheck(configuration["CatalogUrlHC"], TimeSpan.FromMinutes(minutes)); - checks.AddUrlCheck(configuration["OrderingUrlHC"], TimeSpan.FromMinutes(minutes)); - checks.AddUrlCheck(configuration["BasketUrlHC"], TimeSpan.Zero); //No cache for this HealthCheck, better just for demos - checks.AddUrlCheck(configuration["IdentityUrlHC"], TimeSpan.FromMinutes(minutes)); - checks.AddUrlCheck(configuration["MarketingUrlHC"], TimeSpan.FromMinutes(minutes)); - }); - - return services; - } - - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - services.Configure(configuration); - - services.AddMvc(); - - services.AddSession(); - - if (configuration.GetValue("IsClusterEnv") == bool.TrueString) - { - services.AddDataProtection(opts => - { - opts.ApplicationDiscriminator = "eshop.webmvc"; - }) - .PersistKeysToRedis(ConnectionMultiplexer.Connect(configuration["DPConnectionString"]), "DataProtection-Keys"); - } - return services; - } - - // Adds all Http client services (like Service-Agents) using resilient Http requests based on HttpClient factory and Polly's policies - public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) - { - services.AddSingleton(); - - //register delegating handlers - services.AddTransient(); - services.AddTransient(); - - //set 5 min as the lifetime for each HttpMessageHandler int the pool - services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5)); - - //add http client services - services.AddHttpClient() - .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddHttpMessageHandler() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - //add custom application services - services.AddTransient, IdentityParser>(); - - return services; - } - - public static IServiceCollection AddHttpClientLogging(this IServiceCollection services, IConfiguration configuration) - { - services.AddLogging(b => - { - b.AddFilter((category, level) => true); // Spam the world with logs. - - // Add console logger so we can see all the logging produced by the client by default. - b.AddConsole(c => c.IncludeScopes = true); - - // Add console logger - b.AddDebug(); - }); - - return services; - } - - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - var useLoadTest = configuration.GetValue("UseLoadTest"); - var identityUrl = configuration.GetValue("IdentityUrl"); - var callBackUrl = configuration.GetValue("CallBackUrl"); - - // Add Authentication services - - services.AddAuthentication(options => - { - options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; - }) - .AddCookie() - .AddOpenIdConnect(options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.Authority = identityUrl.ToString(); - options.SignedOutRedirectUri = callBackUrl.ToString(); - options.ClientId = useLoadTest ? "mvctest" : "mvc"; - options.ClientSecret = "secret"; - options.ResponseType = useLoadTest ? "code id_token token" : "code id_token"; - options.SaveTokens = true; - options.GetClaimsFromUserInfoEndpoint = true; - options.RequireHttpsMetadata = false; - options.Scope.Add("openid"); - options.Scope.Add("profile"); - options.Scope.Add("orders"); - options.Scope.Add("basket"); - options.Scope.Add("marketing"); - options.Scope.Add("locations"); - options.Scope.Add("webshoppingagg"); - options.Scope.Add("orders.signalrhub"); - }); - - return services; - } - - static IAsyncPolicy GetRetryPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) - .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); - - } - static IAsyncPolicy GetCircuitBreakerPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); - } - } + app.UseSession(); + app.UseStaticFiles(); + + if (Configuration.GetValue("UseLoadTest")) + { + app.UseMiddleware(); + } + + app.UseAuthentication(); + + ILogger log = loggerFactory.CreateLogger("identity"); + + WebContextSeed.Seed(app, env, loggerFactory); + + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Catalog}/{action=Index}/{id?}"); + + routes.MapRoute( + name: "defaultError", + template: "{controller=Error}/{action=Error}"); + }); + } + } + + static class ServiceCollectionExtensions + { + + public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) + { + services.AddApplicationInsightsTelemetry(configuration); + string orchestratorType = configuration.GetValue("OrchestratorType"); + + if (orchestratorType?.ToUpper() == "K8S") + { + // Enable K8s telemetry initializer + services.EnableKubernetes(); + } + + if (orchestratorType?.ToUpper() == "SF") + { + // Enable SF telemetry initializer + services.AddSingleton((serviceProvider) => + new FabricTelemetryInitializer()); + } + + return services; + } + + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + services.AddHealthChecks(checks => + { + int minutes = 1; + if (int.TryParse(configuration["HealthCheck:Timeout"], out int minutesParsed)) + { + minutes = minutesParsed; + } + + checks.AddUrlCheck(configuration["CatalogUrlHC"], TimeSpan.FromMinutes(minutes)); + checks.AddUrlCheck(configuration["OrderingUrlHC"], TimeSpan.FromMinutes(minutes)); + checks.AddUrlCheck(configuration["BasketUrlHC"], TimeSpan.Zero); //No cache for this HealthCheck, better just for demos + checks.AddUrlCheck(configuration["IdentityUrlHC"], TimeSpan.FromMinutes(minutes)); + checks.AddUrlCheck(configuration["MarketingUrlHC"], TimeSpan.FromMinutes(minutes)); + }); + + return services; + } + + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) + { + services.AddOptions(); + services.Configure(configuration); + + services.AddMvc(opts=> + { + opts.SslPort = 4100; + opts.RequireHttpsPermanent = true; + }); + + services.AddSession(); + + if (configuration.GetValue("IsClusterEnv") == bool.TrueString) + { + services.AddDataProtection(opts => + { + opts.ApplicationDiscriminator = "eshop.webmvc"; + }) + .PersistKeysToRedis(ConnectionMultiplexer.Connect(configuration["DPConnectionString"]), "DataProtection-Keys"); + } + return services; + } + + // Adds all Http client services (like Service-Agents) using resilient Http requests based on HttpClient factory and Polly's policies + public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) + { + services.AddSingleton(); + + //register delegating handlers + services.AddTransient(); + services.AddTransient(); + + //set 5 min as the lifetime for each HttpMessageHandler int the pool + services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5)); + + //add http client services + services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddHttpMessageHandler() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + //add custom application services + services.AddTransient, IdentityParser>(); + + return services; + } + + public static IServiceCollection AddHttpClientLogging(this IServiceCollection services, IConfiguration configuration) + { + services.AddLogging(b => + { + b.AddFilter((category, level) => true); // Spam the world with logs. + + // Add console logger so we can see all the logging produced by the client by default. + b.AddConsole(c => c.IncludeScopes = true); + + // Add console logger + b.AddDebug(); + }); + + return services; + } + + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { + bool useLoadTest = configuration.GetValue("UseLoadTest"); + string identityUrl = configuration.GetValue("IdentityUrl"); + string callBackUrl = configuration.GetValue("CallBackUrl"); + + // Add Authentication services + + services.AddAuthentication(options => + { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; + }) + .AddCookie() + .AddOpenIdConnect(options => + { + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.Authority = identityUrl.ToString(); + options.SignedOutRedirectUri = callBackUrl.ToString(); + options.ClientId = useLoadTest ? "mvctest" : "mvc"; + options.ClientSecret = "secret"; + options.ResponseType = useLoadTest ? "code id_token token" : "code id_token"; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.RequireHttpsMetadata = false; + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("orders"); + options.Scope.Add("basket"); + options.Scope.Add("marketing"); + options.Scope.Add("locations"); + options.Scope.Add("webshoppingagg"); + options.Scope.Add("orders.signalrhub"); + }); + + return services; + } + + static IAsyncPolicy GetRetryPolicy() + { + return HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + + } + static IAsyncPolicy GetCircuitBreakerPolicy() + { + return HttpPolicyExtensions + .HandleTransientHttpError() + .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); + } + } } diff --git a/src/Web/WebMVC/Views/Home/Privacy.cshtml b/src/Web/WebMVC/Views/Home/Privacy.cshtml new file mode 100644 index 000000000..7bd38619c --- /dev/null +++ b/src/Web/WebMVC/Views/Home/Privacy.cshtml @@ -0,0 +1,6 @@ +@{ + ViewData["Title"] = "Privacy Policy"; +} +

@ViewData["Title"]

+ +

Use this page to detail your site's privacy policy.

diff --git a/src/Web/WebMVC/Views/Shared/_CookieConsentPartial.cshtml b/src/Web/WebMVC/Views/Shared/_CookieConsentPartial.cshtml new file mode 100644 index 000000000..bbfbb09ac --- /dev/null +++ b/src/Web/WebMVC/Views/Shared/_CookieConsentPartial.cshtml @@ -0,0 +1,41 @@ +@using Microsoft.AspNetCore.Http.Features + +@{ + var consentFeature = Context.Features.Get(); + var showBanner = !consentFeature?.CanTrack ?? false; + var cookieString = consentFeature?.CreateConsentCookie(); +} + +@if (showBanner) +{ + + +} \ No newline at end of file diff --git a/src/Web/WebMVC/Views/Shared/_Layout.cshtml b/src/Web/WebMVC/Views/Shared/_Layout.cshtml index 5f099fe89..484d1c3ff 100644 --- a/src/Web/WebMVC/Views/Shared/_Layout.cshtml +++ b/src/Web/WebMVC/Views/Shared/_Layout.cshtml @@ -1,5 +1,5 @@  - + @@ -49,8 +49,9 @@ - @RenderBody() + + @RenderBody()