mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-07 16:19:07 +00:00
fix(backend): sanitize exception disclosure in changed API endpoints
Replace raw exception-message disclosure (ex.Message) returned to API callers with a stable sanitized public message plus correlated structured internal logging, across the endpoints changed in this PR. - Add SanitizedErrors helper: logs the original exception at Error with a generated correlation id and returns a stable public message referencing it so support can trace without exposing internals. - Inject ILogger<T> into the 14 changed controllers and route every ex.Message/dbex.Message disclosure through the helper, preserving status codes, response shapes, and business data (e.g. OpenWorkOrders). - Leave FluentValidation (vex.Errors) and existing fixed-message catches untouched; out-of-scope controllers (Account/Contact/Employee/Asset/ PMSchedule) are unchanged. - Add focused tests proving internal exception text is not returned and that Error logging carrying the original exception is invoked.
This commit is contained in:
parent
6f6c7e04cd
commit
32de36f78c
26 changed files with 386 additions and 99 deletions
|
|
@ -4,6 +4,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -20,7 +21,7 @@ public class AuthenticationControllerTests
|
|||
|
||||
private static AuthenticationController NewController(Mock<IAuthenticationService> service, string? userId = null)
|
||||
{
|
||||
var controller = new AuthenticationController(service.Object);
|
||||
var controller = new AuthenticationController(service.Object, Mock.Of<ILogger<AuthenticationController>>());
|
||||
if (userId != null)
|
||||
{
|
||||
controller.ControllerContext = new ControllerContext
|
||||
|
|
@ -82,6 +83,35 @@ public class AuthenticationControllerTests
|
|||
result.Should().BeOfType<UnauthorizedResult>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Login_WhenServiceThrows_ReturnsSanitized500AndLogsInternally()
|
||||
{
|
||||
var service = new Mock<IAuthenticationService>();
|
||||
service.Setup(s => s.LoginAsync(It.IsAny<string?>(), It.IsAny<string?>(), It.IsAny<CancellationToken>()))
|
||||
.ThrowsAsync(new InvalidOperationException("SECRET-internal-stack-detail"));
|
||||
|
||||
var logger = new Mock<ILogger<AuthenticationController>>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var controller = new AuthenticationController(service.Object, logger.Object);
|
||||
|
||||
var result = await controller.Login(new LoginModel { Username = "x", Password = "y" }, CancellationToken.None);
|
||||
|
||||
var status = result.Should().BeOfType<ObjectResult>().Subject;
|
||||
status.StatusCode.Should().Be(500);
|
||||
var message = (string)status.Value!;
|
||||
message.Should().NotContain("SECRET");
|
||||
message.Should().NotContain("internal-stack-detail");
|
||||
message.Should().Contain("reference");
|
||||
logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.Is<Exception>(ex => ex.Message.Contains("SECRET")),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ChangePassword_Success_ReturnsSuccessMessageWithTrailingSpace()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Api.SeaHavenIndustries.DTOs;
|
|||
using Data.SeaHavenIndustries;
|
||||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -26,7 +27,7 @@ public class CalendarControllerTests
|
|||
};
|
||||
|
||||
private static CalendarController NewController(Mock<ICalendarService> service) =>
|
||||
new(service.Object);
|
||||
new(service.Object, Mock.Of<ILogger<CalendarController>>());
|
||||
|
||||
private static object Prop(object source, string name) =>
|
||||
source.GetType().GetProperty(name)!.GetValue(source)!;
|
||||
|
|
@ -45,17 +46,32 @@ public class CalendarControllerTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddEvent_WhenServiceThrows_ReturnsBadRequestWithMessage()
|
||||
public async Task AddEvent_WhenServiceThrows_ReturnsSanitizedMessageAndLogsInternally()
|
||||
{
|
||||
var service = new Mock<ICalendarService>();
|
||||
service.Setup(s => s.CreateEventAsync(It.IsAny<EditEventInput>(), It.IsAny<CancellationToken>()))
|
||||
.ThrowsAsync(new InvalidOperationException("boom"));
|
||||
.ThrowsAsync(new InvalidOperationException("SECRET-internal-db-connection-leak"));
|
||||
|
||||
var result = await NewController(service).AddEvent(ValidDto(), CancellationToken.None);
|
||||
var logger = new Mock<ILogger<CalendarController>>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var controller = new CalendarController(service.Object, logger.Object);
|
||||
|
||||
var result = await controller.AddEvent(ValidDto(), CancellationToken.None);
|
||||
|
||||
var bad = result.Should().BeOfType<BadRequestObjectResult>().Subject;
|
||||
var response = bad.Value.Should().BeOfType<Response>().Subject;
|
||||
response.Message.Should().Be("boom");
|
||||
response.Status.Should().Be("Error");
|
||||
response.Message.Should().NotContain("SECRET");
|
||||
response.Message.Should().NotContain("internal-db-connection-leak");
|
||||
response.Message.Should().Contain("reference");
|
||||
logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.Is<Exception>(ex => ex.Message.Contains("SECRET")),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -16,7 +17,7 @@ public class FollowUpControllerTests
|
|||
{
|
||||
private static FollowUpController NewController(Mock<IFollowUpService> service)
|
||||
{
|
||||
var controller = new FollowUpController(service.Object)
|
||||
var controller = new FollowUpController(service.Object, Mock.Of<ILogger<FollowUpController>>())
|
||||
{
|
||||
ControllerContext = new ControllerContext
|
||||
{
|
||||
|
|
@ -33,7 +34,7 @@ public class FollowUpControllerTests
|
|||
}
|
||||
|
||||
private static FollowUpController NewControllerNoUser(Mock<IFollowUpService> service) =>
|
||||
new(service.Object)
|
||||
new(service.Object, Mock.Of<ILogger<FollowUpController>>())
|
||||
{
|
||||
ControllerContext = new ControllerContext
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -14,7 +15,7 @@ namespace Api.SeaHavenIndustries.Tests;
|
|||
public class LocationControllerTests
|
||||
{
|
||||
private static LocationController NewController(Mock<ILocationService> service) =>
|
||||
new(service.Object);
|
||||
new(service.Object, Mock.Of<ILogger<LocationController>>());
|
||||
|
||||
private static object Prop(object source, string name) =>
|
||||
source.GetType().GetProperty(name)!.GetValue(source)!;
|
||||
|
|
|
|||
71
Api.SeaHavenIndustries.Tests/SanitizedErrorsTests.cs
Normal file
71
Api.SeaHavenIndustries.Tests/SanitizedErrorsTests.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using Api.SeaHavenIndustries.Helper;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Tests;
|
||||
|
||||
public class SanitizedErrorsTests
|
||||
{
|
||||
[Fact]
|
||||
public void Sanitize_ReturnsStableMessageAndNeverExposesExceptionText()
|
||||
{
|
||||
var logger = new Mock<ILogger>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
|
||||
var message = logger.Object.Sanitize(new InvalidOperationException("SUPER-SECRET-internal-detail"));
|
||||
|
||||
message.Should().NotContain("SUPER-SECRET");
|
||||
message.Should().NotContain("internal-detail");
|
||||
message.Should().StartWith("An unexpected error occurred");
|
||||
message.Should().Contain("reference");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sanitize_UsesProvidedPublicMessageInsteadOfExceptionText()
|
||||
{
|
||||
var logger = new Mock<ILogger>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
|
||||
var message = logger.Object.Sanitize(
|
||||
new InvalidOperationException("SUPER-SECRET-internal-detail"),
|
||||
"Vendor not found");
|
||||
|
||||
message.Should().Contain("Vendor not found");
|
||||
message.Should().NotContain("SUPER-SECRET");
|
||||
message.Should().Contain("reference");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sanitize_LogsOriginalExceptionAtErrorLevel()
|
||||
{
|
||||
var logger = new Mock<ILogger>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var exception = new InvalidOperationException("SUPER-SECRET-internal-detail");
|
||||
|
||||
logger.Object.Sanitize(exception);
|
||||
|
||||
logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.Is<Exception>(ex => ex == exception),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sanitize_ProducesUniqueCorrelationReferencesAcrossCalls()
|
||||
{
|
||||
var logger = new Mock<ILogger>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var exception = new InvalidOperationException("detail");
|
||||
|
||||
var first = logger.Object.Sanitize(exception);
|
||||
var second = logger.Object.Sanitize(exception);
|
||||
|
||||
first.Should().NotBe(second);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ using Api.SeaHavenIndustries.Helper.ViewModel;
|
|||
using Data.SeaHavenIndustries;
|
||||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -14,7 +15,7 @@ namespace Api.SeaHavenIndustries.Tests;
|
|||
public class SettingsControllerTests
|
||||
{
|
||||
private static SettingsController NewController(Mock<ISettingsService> service) =>
|
||||
new(service.Object);
|
||||
new(service.Object, Mock.Of<ILogger<SettingsController>>());
|
||||
|
||||
[Fact]
|
||||
public async Task GetCategoryList_ReturnsPaginationEnvelopeWithServiceItems()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -15,7 +16,7 @@ public class UpliftControllerTests
|
|||
{
|
||||
private static UpliftController NewController(Mock<IUpliftService> service, params string[] roles)
|
||||
{
|
||||
var controller = new UpliftController(service.Object);
|
||||
var controller = new UpliftController(service.Object, Mock.Of<ILogger<UpliftController>>());
|
||||
var claims = new List<Claim> { new(ClaimTypes.NameIdentifier, "42") };
|
||||
claims.AddRange(roles.Select(r => new Claim(ClaimTypes.Role, r)));
|
||||
controller.ControllerContext = new ControllerContext
|
||||
|
|
@ -66,6 +67,41 @@ public class UpliftControllerTests
|
|||
nf.Value.Should().BeOfType<Response>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Approve_Forbidden_ReturnsSanitized403AndLogsInternally()
|
||||
{
|
||||
var service = new Mock<IUpliftService>();
|
||||
service.Setup(x => x.ApproveAsync(It.IsAny<ClaimsPrincipal>(), 5, null, It.IsAny<CancellationToken>()))
|
||||
.ThrowsAsync(new UpliftForbiddenException("SECRET-tier-restriction-detail"));
|
||||
|
||||
var logger = new Mock<ILogger<UpliftController>>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var controller = new UpliftController(service.Object, logger.Object);
|
||||
controller.ControllerContext = new ControllerContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "42") }, "Test"))
|
||||
}
|
||||
};
|
||||
|
||||
var result = await controller.Approve(5, null);
|
||||
|
||||
var status = result.Should().BeOfType<ObjectResult>().Subject;
|
||||
status.StatusCode.Should().Be(403);
|
||||
var response = status.Value.Should().BeOfType<Response>().Subject;
|
||||
response.Message.Should().NotContain("SECRET");
|
||||
response.Message.Should().Contain("reference");
|
||||
logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.Is<Exception>(ex => ex.Message.Contains("SECRET")),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Approve_ForbiddenTier_Returns403()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -20,7 +21,7 @@ public class UserControllerTests
|
|||
|
||||
private static UserController NewController(Mock<IUserService> service, string? userId = null)
|
||||
{
|
||||
var controller = new UserController(service.Object);
|
||||
var controller = new UserController(service.Object, Mock.Of<ILogger<UserController>>());
|
||||
if (userId != null)
|
||||
{
|
||||
controller.ControllerContext = new ControllerContext
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -16,7 +17,7 @@ public class VendorControllerTests
|
|||
{
|
||||
private static VendorController NewController(Mock<IVendorService> service)
|
||||
{
|
||||
var controller = new VendorController(service.Object);
|
||||
var controller = new VendorController(service.Object, Mock.Of<ILogger<VendorController>>());
|
||||
|
||||
controller.ControllerContext = new ControllerContext
|
||||
{
|
||||
|
|
@ -218,6 +219,44 @@ public class VendorControllerTests
|
|||
result.Should().BeOfType<NotFoundResult>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Delete_WhenDeactivationBlocked_ReturnsSanitizedConflictWithOpenWorkOrdersAndLogs()
|
||||
{
|
||||
var openWorkOrders = new List<LinkedWorkOrderDTO> { new() { WorkOrderId = 7 } };
|
||||
var service = new Mock<IVendorService>();
|
||||
service.Setup(x => x.DeleteVendorAsync(It.IsAny<int>(), It.IsAny<string>()))
|
||||
.ThrowsAsync(new VendorDeactivationBlockedException("SECRET-internal-reason", openWorkOrders));
|
||||
|
||||
var logger = new Mock<ILogger<VendorController>>();
|
||||
logger.Setup(x => x.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
|
||||
var controller = new VendorController(service.Object, logger.Object);
|
||||
controller.ControllerContext = new ControllerContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "42") }, "Test"))
|
||||
}
|
||||
};
|
||||
|
||||
var result = await controller.Delete(5);
|
||||
|
||||
var conflict = result.Should().BeOfType<ConflictObjectResult>().Subject;
|
||||
var value = conflict.Value!;
|
||||
var message = (string)value.GetType().GetProperty("Message")!.GetValue(value)!;
|
||||
message.Should().NotContain("SECRET");
|
||||
message.Should().Contain("reference");
|
||||
var returnedOpenWorkOrders = (List<LinkedWorkOrderDTO>)value.GetType().GetProperty("OpenWorkOrders")!.GetValue(value)!;
|
||||
returnedOpenWorkOrders.Should().HaveCount(1);
|
||||
logger.Verify(
|
||||
x => x.Log(
|
||||
LogLevel.Error,
|
||||
It.IsAny<EventId>(),
|
||||
It.IsAny<It.IsAnyType>(),
|
||||
It.Is<Exception>(ex => ex.Message.Contains("SECRET")),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Delete_MapsDeactivationBlocked_ToConflict()
|
||||
{
|
||||
|
|
@ -265,7 +304,7 @@ public class VendorControllerTests
|
|||
public async Task Update_UnauthenticatedUser_ReturnsUnauthorized()
|
||||
{
|
||||
var service = new Mock<IVendorService>();
|
||||
var controller = new VendorController(service.Object);
|
||||
var controller = new VendorController(service.Object, Mock.Of<ILogger<VendorController>>());
|
||||
controller.ControllerContext = new ControllerContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal() }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Data.SeaHavenIndustries;
|
|||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
|
@ -14,7 +15,7 @@ public class VendorPortalControllerTests
|
|||
{
|
||||
private static VendorPortalController NewController(Mock<IVendorPortalService> service, string? token = "valid-token")
|
||||
{
|
||||
var controller = new VendorPortalController(service.Object);
|
||||
var controller = new VendorPortalController(service.Object, Mock.Of<ILogger<VendorPortalController>>());
|
||||
var context = new DefaultHttpContext();
|
||||
if (token != null)
|
||||
context.Request.Headers["X-Vendor-Token"] = token;
|
||||
|
|
@ -133,7 +134,8 @@ public class VendorPortalControllerTests
|
|||
|
||||
var bad = result.Should().BeOfType<BadRequestObjectResult>().Subject;
|
||||
var resp = bad.Value.Should().BeOfType<Response>().Subject;
|
||||
resp.Message.Should().Be("Cannot accept");
|
||||
resp.Message.Should().NotContain("Cannot accept");
|
||||
resp.Message.Should().Contain("reference");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -169,7 +171,8 @@ public class VendorPortalControllerTests
|
|||
|
||||
var bad = result.Should().BeOfType<BadRequestObjectResult>().Subject;
|
||||
var resp = bad.Value.Should().BeOfType<Response>().Subject;
|
||||
resp.Message.Should().Contain("Transition");
|
||||
resp.Message.Should().NotContain("Transition");
|
||||
resp.Message.Should().Contain("reference");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -24,4 +24,8 @@
|
|||
<ProjectReference Include="..\SeaHaven.DataServices\SeaHaven.DataServices.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="Api.SeaHavenIndustries.Tests" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using System.Security.Claims;
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class AuthenticationController : Controller
|
||||
{
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
private readonly ILogger<AuthenticationController> _logger;
|
||||
|
||||
public AuthenticationController(IAuthenticationService authenticationService)
|
||||
public AuthenticationController(IAuthenticationService authenticationService, ILogger<AuthenticationController> logger)
|
||||
{
|
||||
_authenticationService = authenticationService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
|
|
@ -46,7 +50,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
catch (Exception ex)
|
||||
{
|
||||
|
||||
return StatusCode(500, ex.Message);
|
||||
return StatusCode(500, _logger.Sanitize(ex));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -94,7 +98,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +139,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "Error: " + ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +163,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
catch (Exception ex)
|
||||
{
|
||||
|
||||
return BadRequest(new Response { Status = "Error", Message = "Error: " + ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class CalendarController : Controller
|
||||
{
|
||||
private readonly ICalendarService _calendarService;
|
||||
private readonly ILogger<CalendarController> _logger;
|
||||
|
||||
public CalendarController(ICalendarService calendarService)
|
||||
public CalendarController(ICalendarService calendarService, ILogger<CalendarController> logger)
|
||||
{
|
||||
_calendarService = calendarService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
|
|
@ -34,7 +38,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +66,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +90,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +113,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +139,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +158,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Api.SeaHavenIndustries.Helper.ViewModel;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class CommonController : Controller
|
||||
{
|
||||
private readonly ICommonService _commonService;
|
||||
private readonly ILogger<CommonController> _logger;
|
||||
|
||||
public CommonController(ICommonService commonService)
|
||||
public CommonController(ICommonService commonService, ILogger<CommonController> logger)
|
||||
{
|
||||
_commonService = commonService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
|
@ -49,7 +53,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +69,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -12,10 +14,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class DropdownOptionsController : Controller
|
||||
{
|
||||
private readonly IDropdownOptionsService _dropdownOptionsService;
|
||||
private readonly ILogger<DropdownOptionsController> _logger;
|
||||
|
||||
public DropdownOptionsController(IDropdownOptionsService dropdownOptionsService)
|
||||
public DropdownOptionsController(IDropdownOptionsService dropdownOptionsService, ILogger<DropdownOptionsController> logger)
|
||||
{
|
||||
_dropdownOptionsService = dropdownOptionsService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
|
@ -42,7 +46,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new { message = ex.Message });
|
||||
return BadRequest(new { message = _logger.Sanitize(ex, "The dropdown option could not be saved") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
using System.Security.Claims;
|
||||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -14,10 +16,12 @@ using SeaHaven.Services.Interfaces;
|
|||
public class FollowUpController : ControllerBase
|
||||
{
|
||||
private readonly IFollowUpService _followUpService;
|
||||
private readonly ILogger<FollowUpController> _logger;
|
||||
|
||||
public FollowUpController(IFollowUpService followUpService)
|
||||
public FollowUpController(IFollowUpService followUpService, ILogger<FollowUpController> logger)
|
||||
{
|
||||
_followUpService = followUpService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("GetFollowUpList")]
|
||||
|
|
@ -111,7 +115,7 @@ public class FollowUpController : ControllerBase
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +138,7 @@ public class FollowUpController : ControllerBase
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +177,7 @@ public class FollowUpController : ControllerBase
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -15,10 +17,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class LocationController : Controller
|
||||
{
|
||||
private readonly ILocationService _locationService;
|
||||
private readonly ILogger<LocationController> _logger;
|
||||
|
||||
public LocationController(ILocationService locationService)
|
||||
public LocationController(ILocationService locationService, ILogger<LocationController> logger)
|
||||
{
|
||||
_locationService = locationService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("GetLocationList")]
|
||||
|
|
@ -98,7 +102,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +125,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +146,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class QuotesController : Controller
|
||||
{
|
||||
private readonly IQuotesService _quotesService;
|
||||
private readonly ILogger<QuotesController> _logger;
|
||||
|
||||
public QuotesController(IQuotesService quotesService)
|
||||
public QuotesController(IQuotesService quotesService, ILogger<QuotesController> logger)
|
||||
{
|
||||
_quotesService = quotesService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
|
@ -31,7 +35,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +53,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +72,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Api.SeaHavenIndustries.Helper.ViewModel;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class SettingsController : Controller
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILogger<SettingsController> _logger;
|
||||
|
||||
public SettingsController(ISettingsService settingsService)
|
||||
public SettingsController(ISettingsService settingsService, ILogger<SettingsController> logger)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
|
@ -30,7 +34,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +51,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +68,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +113,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +149,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +165,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -14,10 +16,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class TaskListTemplateController : Controller
|
||||
{
|
||||
private readonly ITaskListTemplateService _taskListTemplateService;
|
||||
private readonly ILogger<TaskListTemplateController> _logger;
|
||||
|
||||
public TaskListTemplateController(ITaskListTemplateService taskListTemplateService)
|
||||
public TaskListTemplateController(ITaskListTemplateService taskListTemplateService, ILogger<TaskListTemplateController> logger)
|
||||
{
|
||||
_taskListTemplateService = taskListTemplateService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
|
@ -49,7 +53,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +71,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class UpliftController : Controller
|
||||
{
|
||||
private readonly IUpliftService _upliftService;
|
||||
private readonly ILogger<UpliftController> _logger;
|
||||
|
||||
public UpliftController(IUpliftService upliftService)
|
||||
public UpliftController(IUpliftService upliftService, ILogger<UpliftController> logger)
|
||||
{
|
||||
_upliftService = upliftService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
|
@ -43,15 +47,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(new Response { Status = "Error", Message = ex.Message });
|
||||
return NotFound(new Response { Status = "Error", Message = _logger.Sanitize(ex, "Uplift request not found") });
|
||||
}
|
||||
catch (UpliftForbiddenException ex)
|
||||
{
|
||||
return StatusCode(403, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(403, new Response { Status = "Error", Message = _logger.Sanitize(ex, "You are not authorized to perform this action on this uplift request") });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "This uplift request cannot be modified in its current state") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +69,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (KeyNotFoundException ex)
|
||||
{
|
||||
return NotFound(new Response { Status = "Error", Message = ex.Message });
|
||||
return NotFound(new Response { Status = "Error", Message = _logger.Sanitize(ex, "Uplift request not found") });
|
||||
}
|
||||
catch (UpliftForbiddenException ex)
|
||||
{
|
||||
return StatusCode(403, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(403, new Response { Status = "Error", Message = _logger.Sanitize(ex, "You are not authorized to perform this action on this uplift request") });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "This uplift request cannot be modified in its current state") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using System.Security.Claims;
|
||||
|
|
@ -14,10 +16,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class UserController : Controller
|
||||
{
|
||||
private readonly IUserService _userService;
|
||||
private readonly ILogger<UserController> _logger;
|
||||
|
||||
public UserController(IUserService userService)
|
||||
public UserController(IUserService userService, ILogger<UserController> logger)
|
||||
{
|
||||
_userService = userService;
|
||||
_logger = logger;
|
||||
}
|
||||
[Route("")]
|
||||
[HttpGet]
|
||||
|
|
@ -49,7 +53,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +77,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +97,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +113,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using System.Security.Claims;
|
||||
|
|
@ -16,10 +18,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class VendorController : Controller
|
||||
{
|
||||
private readonly IVendorService _vendorService;
|
||||
private readonly ILogger<VendorController> _logger;
|
||||
|
||||
public VendorController(IVendorService vendorService)
|
||||
public VendorController(IVendorService vendorService, ILogger<VendorController> logger)
|
||||
{
|
||||
_vendorService = vendorService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("GetVendorList")]
|
||||
|
|
@ -148,7 +152,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +203,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
return Conflict(new
|
||||
{
|
||||
Status = "Conflict",
|
||||
Message = dbex.Message,
|
||||
Message = _logger.Sanitize(dbex, "Vendor cannot be deactivated because it has open work orders"),
|
||||
OpenWorkOrders = dbex.OpenWorkOrders
|
||||
});
|
||||
}
|
||||
|
|
@ -209,7 +213,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +240,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
return Conflict(new
|
||||
{
|
||||
Status = "Conflict",
|
||||
Message = dbex.Message,
|
||||
Message = _logger.Sanitize(dbex, "Vendor cannot be deactivated because it has open work orders"),
|
||||
OpenWorkOrders = dbex.OpenWorkOrders
|
||||
});
|
||||
}
|
||||
|
|
@ -246,7 +250,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +268,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +308,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new Response { Status = "Error", Message = ex.Message });
|
||||
return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
|
|
@ -13,10 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
private const string TokenHeader = "X-Vendor-Token";
|
||||
|
||||
private readonly IVendorPortalService _portalService;
|
||||
private readonly ILogger<VendorPortalController> _logger;
|
||||
|
||||
public VendorPortalController(IVendorPortalService portalService)
|
||||
public VendorPortalController(IVendorPortalService portalService, ILogger<VendorPortalController> logger)
|
||||
{
|
||||
_portalService = portalService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("session")]
|
||||
|
|
@ -71,7 +75,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +96,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +117,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +138,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +159,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +180,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +201,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +222,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The requested action could not be completed for this dispatch") });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using Api.SeaHavenIndustries.DTOs;
|
||||
using Api.SeaHavenIndustries.Helper;
|
||||
using Data.SeaHavenIndustries;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.DataServices.Models;
|
||||
|
|
@ -18,13 +20,16 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
private readonly IWorkOrderService _workOrderService;
|
||||
private readonly IWorkOrderDispatchService _dispatchService;
|
||||
private readonly ILogger<WorkOrderController> _logger;
|
||||
|
||||
public WorkOrderController(
|
||||
IWorkOrderService workOrderService,
|
||||
IWorkOrderDispatchService dispatchService)
|
||||
IWorkOrderDispatchService dispatchService,
|
||||
ILogger<WorkOrderController> logger)
|
||||
{
|
||||
_workOrderService = workOrderService;
|
||||
_dispatchService = dispatchService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
|
@ -60,7 +65,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +112,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +154,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +243,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +262,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +286,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +309,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +370,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +415,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,7 +441,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -458,7 +463,7 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -484,11 +489,11 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex, "The dispatch signoff could not be added") });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
return BadRequest(new Response { Status = "Error", Message = _logger.Sanitize(ex) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
27
Api.SeaHavenIndustries/Helper/SanitizedErrors.cs
Normal file
27
Api.SeaHavenIndustries/Helper/SanitizedErrors.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Helper;
|
||||
|
||||
internal static class SanitizedErrors
|
||||
{
|
||||
private const string DefaultPublicMessage = "An unexpected error occurred";
|
||||
|
||||
public static string Sanitize(
|
||||
this ILogger logger,
|
||||
Exception exception,
|
||||
string? publicMessage = null,
|
||||
[CallerMemberName] string operation = "")
|
||||
{
|
||||
var correlationId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
|
||||
|
||||
logger.LogError(
|
||||
exception,
|
||||
"Unhandled exception in {Operation}. CorrelationId: {CorrelationId}",
|
||||
operation,
|
||||
correlationId);
|
||||
|
||||
return $"{publicMessage ?? DefaultPublicMessage} (reference {correlationId}).";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue