Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/Api/Dirt/Controllers/OrganizationReportsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,8 @@ public async Task<IActionResult> CreateOrganizationReportAsync(

await AuthorizeAsync(organizationId);

// File storage only exists under the new architecture, so gate the file path on the (stable)
// AccessIntelligenceNewArchitecture flag. Within that, select the path from the request shape
// rather than the file-storage flag (AccessIntelligenceVersion2): the client chooses its shape
// from that flag via a config cache that can lag the server by up to an hour (pronounced in
// self-hosted), so branching on it here would 500 whenever the two disagree. Honoring the shape
// lets file-storage flag staleness degrade gracefully.
// File storage only exists under the new architecture, so gate the file path on the
// AccessIntelligenceNewArchitecture flag. Within that, select the path from the request shape.
var isNewArchitecture = _featureService.IsEnabled(FeatureFlagKeys.AccessIntelligenceNewArchitecture);
if (isNewArchitecture && request.FileSize.HasValue)
{
Expand Down
1 change: 0 additions & 1 deletion src/Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ public static partial class FeatureFlagKeys
public const string WindowsNativeCredentialSync = "windows-native-credential-sync";

/* DIRT Team */
public const string AccessIntelligenceVersion2 = "pm-31920-access-intelligence-azure-file-storage";
public const string EventManagementForBlumira = "event-management-for-blumira";
public const string EventManagementForDataDogAndCrowdStrike = "event-management-for-datadog-and-crowdstrike";
public const string EventDiagnosticLogging = "pm-27666-siem-event-log-debugging";
Expand Down
81 changes: 1 addition & 80 deletions test/Api.Test/Dirt/OrganizationReportsControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ await sutProvider.GetDependency<IGetOrganizationReportQuery>()
}

// CreateOrganizationReportAsync - the file path is gated on the new architecture, then selected by
// request shape (FileSize); it is never selected by the file-storage flag.
// request shape (FileSize).

[Theory, BitAutoData]
public async Task CreateOrganizationReportAsync_NewArchOn_WithoutFileSize_TakesInlinePath(
Expand Down Expand Up @@ -358,85 +358,6 @@ await sutProvider.GetDependency<ICreateOrganizationReportCommand>()
.CreateAsync(Arg.Any<AddOrganizationReportRequest>());
}

// Under the new architecture, path selection must be independent of the file-storage flag: the
// client chooses its request shape from that flag via a config cache that can lag the server, so
// branching on it here would fail whenever the client and server disagree.

[Theory, BitAutoData]
public async Task CreateOrganizationReportAsync_NewArchOn_WithFileSize_FileStorageFlagOff_StillTakesFileCreatePath(
SutProvider<OrganizationReportsController> sutProvider,
Guid orgId,
AddOrganizationReportRequestModel request,
OrganizationReport expectedReport,
string uploadUrl)
{
// Arrange - client sent a file-shaped body while the server's file-storage flag is off.
request.FileSize = 1024;

var reportFile = new ReportFile { Id = "file-id", FileName = "report.json", Size = 1024, Validated = false };
expectedReport.SetReportFile(reportFile);

SetupAuthorization(sutProvider, orgId);
SetupNewArchitecture(sutProvider, enabled: true);

sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccessIntelligenceVersion2)
.Returns(false);

sutProvider.GetDependency<ICreateOrganizationReportCommand>()
.CreateAsync(Arg.Any<AddOrganizationReportRequest>())
.Returns(expectedReport);

sutProvider.GetDependency<IOrganizationReportStorageService>()
.GetReportFileUploadUrlAsync(expectedReport, Arg.Any<ReportFile>())
.Returns(uploadUrl);

// Act
var result = await sutProvider.Sut.CreateOrganizationReportAsync(orgId, request);

// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
Assert.IsType<OrganizationReportFileResponseModel>(okResult.Value);

await sutProvider.GetDependency<ICreateOrganizationReportCommand>()
.Received(1)
.CreateAsync(Arg.Any<AddOrganizationReportRequest>());
}

[Theory, BitAutoData]
public async Task CreateOrganizationReportAsync_NewArchOn_WithoutFileSize_FileStorageFlagOn_StillTakesInlinePath(
SutProvider<OrganizationReportsController> sutProvider,
Guid orgId,
AddOrganizationReportRequestModel request,
OrganizationReport expectedReport)
{
// Arrange - client sent an inline body while the server's file-storage flag is on.
request.FileSize = null;
expectedReport.ReportFile = null;

SetupAuthorization(sutProvider, orgId);
SetupNewArchitecture(sutProvider, enabled: true);

sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccessIntelligenceVersion2)
.Returns(true);

sutProvider.GetDependency<IAddOrganizationReportCommand>()
.AddOrganizationReportAsync(Arg.Any<AddOrganizationReportRequest>())
.Returns(expectedReport);

// Act
var result = await sutProvider.Sut.CreateOrganizationReportAsync(orgId, request);

// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
Assert.IsType<OrganizationReportResponseModel>(okResult.Value);

await sutProvider.GetDependency<IAddOrganizationReportCommand>()
.Received(1)
.AddOrganizationReportAsync(Arg.Any<AddOrganizationReportRequest>());
}

[Theory, BitAutoData]
public async Task CreateOrganizationReportAsync_EmptyOrgId_ThrowsBadRequestException(
SutProvider<OrganizationReportsController> sutProvider,
Expand Down
Loading