diff --git a/api/Hmcr.Api/Extensions/IApplicationBuilderExtensions.cs b/api/Hmcr.Api/Extensions/IApplicationBuilderExtensions.cs index d3a98b8a..7b37016d 100644 --- a/api/Hmcr.Api/Extensions/IApplicationBuilderExtensions.cs +++ b/api/Hmcr.Api/Extensions/IApplicationBuilderExtensions.cs @@ -14,15 +14,6 @@ namespace Hmcr.Api.Extensions { public static class IApplicationBuilderExtensions { - public static void UseHmcrCors(this IApplicationBuilder app) - { - app.UseCors(builder => builder - .AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader() - .WithExposedHeaders("Content-Disposition")); - } - public static void UseExceptionMiddleware(this IApplicationBuilder app) { app.UseMiddleware(); diff --git a/api/Hmcr.Api/Extensions/IServiceCollectionExtensions.cs b/api/Hmcr.Api/Extensions/IServiceCollectionExtensions.cs index d5216016..6c375661 100644 --- a/api/Hmcr.Api/Extensions/IServiceCollectionExtensions.cs +++ b/api/Hmcr.Api/Extensions/IServiceCollectionExtensions.cs @@ -216,5 +216,19 @@ public static void AddHmcrHealthCheck(this IServiceCollection services, string c services.AddHealthChecks() .AddSqlServer(connectionString, name: "HMCR-DB-Check", failureStatus: HealthStatus.Degraded, tags: new string[] { "sql", "db" }); } + + public static void AddHmcrCors(this IServiceCollection services) + { + services.AddCors(options => + { + options.AddPolicy(name: Constants.HmcrOrigins, + builder => + { + builder.WithOrigins("https://dev-hmcr.th.gov.bc.ca", "https://tst-hmcr.th.gov.bc.ca", "https://uat-hmcr.th.gov.bc.ca", "https://hmcr.th.gov.bc.ca") + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); + } } } diff --git a/api/Hmcr.Api/Startup.cs b/api/Hmcr.Api/Startup.cs index ffce4229..71e748dd 100644 --- a/api/Hmcr.Api/Startup.cs +++ b/api/Hmcr.Api/Startup.cs @@ -4,6 +4,7 @@ using Hmcr.Data.Repositories; using Hmcr.Domain.Hangfire; using Hmcr.Domain.Services; +using Hmcr.Model; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -32,7 +33,7 @@ public void ConfigureServices(IServiceCollection services) services.AddHttpContextAccessor(); services.AddHmcrAuthentication(Configuration); services.AddHmcrDbContext(connectionString); - services.AddCors(); + services.AddHmcrCors(); services.AddHmcrControllers(); services.AddHmcrAutoMapper(); services.AddHmcrApiVersioning(); @@ -51,9 +52,10 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISubmiss app.UseExceptionMiddleware(); app.UseHmcrHealthCheck(); - app.UseAuthorization(); - app.UseAuthentication(); app.UseRouting(); + app.UseCors(Constants.HmcrOrigins); + app.UseAuthentication(); + app.UseAuthorization(); app.UseHmcrEndpoints(); app.UseHmcrSwagger(env, Configuration.GetSection("Constants:SwaggerApiUrl").Value); diff --git a/api/Hmcr.Api/appsettings.json b/api/Hmcr.Api/appsettings.json index 92d3da75..d6affecd 100644 --- a/api/Hmcr.Api/appsettings.json +++ b/api/Hmcr.Api/appsettings.json @@ -1,7 +1,7 @@ { "AllowedHosts": "*", "Constants": { - "Version": "1.2.5.0", + "Version": "1.2.6.0", "SwaggerApiUrl": "/swagger/v1/swagger.json" }, "Serilog": { diff --git a/api/Hmcr.Domain/Services/Base/ReportServiceBase.cs b/api/Hmcr.Domain/Services/Base/ReportServiceBase.cs index c70163cf..40f9d665 100644 --- a/api/Hmcr.Domain/Services/Base/ReportServiceBase.cs +++ b/api/Hmcr.Domain/Services/Base/ReportServiceBase.cs @@ -6,6 +6,7 @@ using Hmcr.Model.Dtos.SubmissionRow; using Hmcr.Model.Dtos.SubmissionStream; using Hmcr.Model.Utils; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; @@ -20,6 +21,7 @@ public abstract class ReportServiceBase protected IUnitOfWork _unitOfWork; protected IFieldValidatorService _validator; protected IServiceAreaService _saService; + private ILogger _logger; protected ISubmissionStreamService _streamService; protected ISubmissionObjectRepository _submissionRepo; protected ISumbissionRowRepository _rowRepo; @@ -46,7 +48,7 @@ public abstract class ReportServiceBase public ReportServiceBase(IUnitOfWork unitOfWork, ISubmissionStreamService streamService, ISubmissionObjectRepository submissionRepo, ISumbissionRowRepository rowRepo, IContractTermRepository contractRepo, ISubmissionStatusService statusService, IFieldValidatorService validator, - IServiceAreaService saService) + IServiceAreaService saService, ILogger logger) { _unitOfWork = unitOfWork; _streamService = streamService; @@ -56,14 +58,21 @@ public ReportServiceBase(IUnitOfWork unitOfWork, _statusService = statusService; _validator = validator; _saService = saService; + _logger = logger; } public async Task<(Dictionary> errors, List resubmittedRecordNumbers)> CheckResubmitAsync(FileUploadDto upload) { if (!HasRowIdentifier) return (new Dictionary>(), null); + var instance = Guid.NewGuid(); + + _logger.LogInformation($"[Api] {instance} Checking resubmit started."); + var (errors, submission) = await ValidateAndLogReportErrorAsync(upload); + _logger.LogInformation($"[Api] {instance} Checking resubmit finished."); + //if there are any errors, just log it and report them to the user. if (errors.Count > 0) return (errors, null); @@ -75,16 +84,23 @@ public ReportServiceBase(IUnitOfWork unitOfWork, public async Task<(decimal submissionObjectId, Dictionary> errors)> CreateReportAsync(FileUploadDto upload) { + var instance = Guid.NewGuid(); + + _logger.LogInformation($"[Api] {instance} Creating report started."); + var (errors, submission) = await ValidateAndLogReportErrorAsync(upload); if (errors.Count > 0) { + _logger.LogInformation($"[Api] {instance} Creating report finished with errors."); return (0, errors); } var submissionEntity = await _submissionRepo.CreateSubmissionObjectAsync(submission); _unitOfWork.Commit(); + _logger.LogInformation($"[Api] {instance} Creating report finished - submission #: {submissionEntity.SubmissionObjectId}"); + return (submissionEntity.SubmissionObjectId, errors); } diff --git a/api/Hmcr.Domain/Services/RockfallReportService.cs b/api/Hmcr.Domain/Services/RockfallReportService.cs index de337d1b..aa143afb 100644 --- a/api/Hmcr.Domain/Services/RockfallReportService.cs +++ b/api/Hmcr.Domain/Services/RockfallReportService.cs @@ -33,7 +33,7 @@ public RockfallReportService(IUnitOfWork unitOfWork, ISubmissionStreamService streamService, ISubmissionObjectRepository submissionRepo, ISumbissionRowRepository rowRepo, IContractTermRepository contractRepo, ISubmissionStatusService statusService, IRockfallReportRepository rockfallRepo, IFieldValidatorService validator, ILogger logger, IServiceAreaService saService) - : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService) + : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService, logger) { TableName = TableNames.RockfallReport; HasRowIdentifier = true; diff --git a/api/Hmcr.Domain/Services/WildlifeReportService.cs b/api/Hmcr.Domain/Services/WildlifeReportService.cs index 1903b685..3bb099d6 100644 --- a/api/Hmcr.Domain/Services/WildlifeReportService.cs +++ b/api/Hmcr.Domain/Services/WildlifeReportService.cs @@ -33,7 +33,7 @@ public WildlifeReportService(IUnitOfWork unitOfWork, ISubmissionStreamService streamService, ISubmissionObjectRepository submissionRepo, ISumbissionRowRepository rowRepo, IContractTermRepository contractRepo, ISubmissionStatusService statusService, IWildlifeReportRepository wildlifeRepo, IFieldValidatorService validator, ILogger logger, IServiceAreaService saService) - : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService) + : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService, logger) { TableName = TableNames.WildlifeReport; HasRowIdentifier = false; diff --git a/api/Hmcr.Domain/Services/WorkReportService.cs b/api/Hmcr.Domain/Services/WorkReportService.cs index 292d5856..e8060ad1 100644 --- a/api/Hmcr.Domain/Services/WorkReportService.cs +++ b/api/Hmcr.Domain/Services/WorkReportService.cs @@ -33,7 +33,7 @@ public WorkReportService(IUnitOfWork unitOfWork, ISubmissionStreamService streamService, ISubmissionObjectRepository submissionRepo, ISumbissionRowRepository rowRepo, IContractTermRepository contractRepo, ISubmissionStatusService statusService, IWorkReportRepository workRptRepo, IFieldValidatorService validator, ILogger logger, IServiceAreaService saService) - : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService) + : base(unitOfWork, streamService, submissionRepo, rowRepo, contractRepo, statusService, validator, saService, logger) { TableName = TableNames.WorkReport; HasRowIdentifier = true; diff --git a/api/Hmcr.Model/Constants.cs b/api/Hmcr.Model/Constants.cs index c1c33f29..3db0b3fe 100644 --- a/api/Hmcr.Model/Constants.cs +++ b/api/Hmcr.Model/Constants.cs @@ -12,6 +12,7 @@ public static class Constants public const string VancouverTimeZone = "America/Vancouver"; public const string PacificTimeZone = "Pacific Standard Time"; public const string SystemAdmin = "SYSTEM_ADMIN"; + public const string HmcrOrigins = "HmcrOrigins"; } public static class Reports diff --git a/client/.env.development b/client/.env.development index e2add909..ecd6b073 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,7 +1,8 @@ BROWSER=none -REACT_APP_API_HOST=http://localhost:27238 +REACT_APP_API_HOST=localhost:27238 +REACT_APP_CLIENT_ORIGIN=localhost:3000 REACT_APP_SSO_CLIENT=hmcr-public-dev REACT_APP_SSO_REALM=fygf50pt -REACT_APP_SSO_HOST=https://sso-dev.pathfinder.gov.bc.ca/auth +REACT_APP_SSO_HOST=https://dev.oidc.gov.bc.ca/auth REACT_APP_DEFAULT_PAGE_SIZE_OPTIONS=25,50,100,200 -REACT_APP_DEFAULT_PAGE_SIZE=25 \ No newline at end of file +REACT_APP_DEFAULT_PAGE_SIZE=25 diff --git a/client/src/js/Api.js b/client/src/js/Api.js index b1880bf8..f9063f81 100644 --- a/client/src/js/Api.js +++ b/client/src/js/Api.js @@ -7,8 +7,10 @@ import { buildApiErrorObject } from './utils'; import * as Constants from './Constants'; export const instance = axios.create({ - baseURL: '/api', - headers: { 'Access-Control-Allow-Origin': '*', Pragma: 'no-cache' }, + baseURL: `${Constants.API_URL}`, + headers: { + Pragma: 'no-cache', + }, }); instance.interceptors.response.use( diff --git a/client/src/js/Constants.js b/client/src/js/Constants.js index db8602b4..186359e7 100644 --- a/client/src/js/Constants.js +++ b/client/src/js/Constants.js @@ -1,6 +1,6 @@ -export const API_URL = window.RUNTIME_REACT_APP_API_HOST - ? `${window.location.protocol}//${window.RUNTIME_REACT_APP_API_HOST}/api` - : process.env.REACT_APP_API_HOST; +export const API_URL = window.RUNTIME_REACT_APP_API_HOST //In non-dev environments, start.sh makes sure the runtime variables are popluated using host environment variables. + ? `${window.location.protocol}//${window.RUNTIME_REACT_APP_API_HOST}/api` //For non-dev environments, CORS is enabled to HMCR urls. + : `${window.location.protocol}//${process.env.REACT_APP_CLIENT_ORIGIN}/api`; //For dev environment, proxy (setupProxy.js) is set up to avoid the same origin policy const CODE_LOOKUP = '/codelookup'; diff --git a/client/src/setupProxy.js b/client/src/setupProxy.js index c493816f..3e2cb50b 100644 --- a/client/src/setupProxy.js +++ b/client/src/setupProxy.js @@ -4,14 +4,14 @@ module.exports = function (app) { app.use( '/api', createProxyMiddleware({ - target: process.env.REACT_APP_API_HOST || 'http://localhost:27238', + target: 'http://' + process.env.REACT_APP_API_HOST, changeOrigin: true, }) ), app.use( '/swagger', createProxyMiddleware({ - target: process.env.REACT_APP_API_HOST || 'http://localhost:27238', + target: 'http://' + process.env.REACT_APP_API_HOST, changeOrigin: true, }) ); diff --git a/openshift/api-deploy-config.yaml b/openshift/api-deploy-config.yaml index 1668dcd1..21453b15 100644 --- a/openshift/api-deploy-config.yaml +++ b/openshift/api-deploy-config.yaml @@ -154,6 +154,25 @@ objects: targetPort: 8080 selector: deploymentconfig: ${NAME}${SUFFIX} + - apiVersion: route.openshift.io/v1 + kind: Route + metadata: + annotations: + haproxy.router.openshift.io/timeout: 1h + creationTimestamp: null + name: ${NAME}${SUFFIX} + spec: + host: api-${HOST} + path: "/" + port: + targetPort: web + tls: + termination: edge + to: + kind: Service + name: ${NAME}${SUFFIX} + weight: 100 + wildcardPolicy: None parameters: - description: Name of the project (HMCR) displayName: PROJECT_NAME diff --git a/openshift/client-deploy-config.yaml b/openshift/client-deploy-config.yaml index 9f99183b..84c7a6d0 100644 --- a/openshift/client-deploy-config.yaml +++ b/openshift/client-deploy-config.yaml @@ -62,7 +62,7 @@ objects: name: sso-configs-${ENV} key: CLIENT_SSO_CLIENTID - name: REACT_APP_API_HOST - value: ${HOST} + value: api-${HOST} - name: HMCR_DEPLOY_SUFFIX value: ${SUFFIX} test: false diff --git a/openshift/configmaps/api-appsettings.yaml b/openshift/configmaps/api-appsettings.yaml index 57f1049b..43adfbdd 100644 --- a/openshift/configmaps/api-appsettings.yaml +++ b/openshift/configmaps/api-appsettings.yaml @@ -9,7 +9,7 @@ objects: { "AllowedHosts": "*", "Constants": { - "Version": "1.2.5.0", + "Version": "1.2.6.0", "SwaggerApiUrl": "/swagger/v1/swagger.json" }, "Serilog": {