1414using Bit . Core . Utilities ;
1515using Microsoft . AspNetCore . Authorization ;
1616using Microsoft . AspNetCore . Mvc ;
17+ using ZiggyCreatures . Caching . Fusion ;
1718
1819namespace Bit . Api . Dirt . Controllers ;
1920
@@ -38,6 +39,7 @@ public class OrganizationReportsController : Controller
3839 private readonly IUpdateOrganizationReportV2Command _updateReportV2Command ;
3940 private readonly IValidateOrganizationReportFileCommand _validateCommand ;
4041 private readonly ILogger < OrganizationReportsController > _logger ;
42+ private readonly IFusionCache _cache ;
4143
4244 public OrganizationReportsController (
4345 ICurrentContext currentContext ,
@@ -56,7 +58,8 @@ public OrganizationReportsController(
5658 IOrganizationReportRepository organizationReportRepo ,
5759 IUpdateOrganizationReportV2Command updateReportV2Command ,
5860 IValidateOrganizationReportFileCommand validateCommand ,
59- ILogger < OrganizationReportsController > logger )
61+ ILogger < OrganizationReportsController > logger ,
62+ [ FromKeyedServices ( OrganizationReportCacheConstants . CacheName ) ] IFusionCache cache )
6063 {
6164 _currentContext = currentContext ;
6265 _getOrganizationReportQuery = getOrganizationReportQuery ;
@@ -75,6 +78,7 @@ public OrganizationReportsController(
7578 _updateReportV2Command = updateReportV2Command ;
7679 _validateCommand = validateCommand ;
7780 _logger = logger ;
81+ _cache = cache ;
7882 }
7983
8084 /// <summary>
@@ -133,7 +137,6 @@ public async Task<IActionResult> CreateOrganizationReportAsync(
133137 /// <summary>
134138 /// Gets the most recent organization report for the specified organization.
135139 /// Includes a presigned download URL for the report file if one has been validated.
136- /// If no file is associated, the response contains inline ReportData.
137140 /// </summary>
138141 /// <param name="organizationId">The unique identifier of the organization.</param>
139142 /// <returns>An <see cref="OrganizationReportResponseModel"/> for the most recent report.</returns>
@@ -156,15 +159,13 @@ public async Task<IActionResult> GetLatestOrganizationReportAsync(Guid organizat
156159
157160 var response = new OrganizationReportResponseModel ( latestReport ) ;
158161
159- var fileData = latestReport . GetReportFile ( ) ;
160- if ( fileData == null )
161- {
162- return Ok ( response ) ;
163- }
164-
165- if ( fileData . Validated )
162+ if ( _featureService . IsEnabled ( FeatureFlagKeys . AccessIntelligenceVersion2 ) )
166163 {
167- response . ReportFileDownloadUrl = await _storageService . GetReportDataDownloadUrlAsync ( latestReport , fileData ) ;
164+ var fileData = latestReport . GetReportFile ( ) ;
165+ if ( fileData is { Validated : true } )
166+ {
167+ response . ReportFileDownloadUrl = await _storageService . GetReportDataDownloadUrlAsync ( latestReport , fileData ) ;
168+ }
168169 }
169170
170171 return Ok ( response ) ;
@@ -174,7 +175,6 @@ public async Task<IActionResult> GetLatestOrganizationReportAsync(Guid organizat
174175 /// Gets a specific organization report by its report ID.
175176 /// Validates that the report belongs to the specified organization.
176177 /// Includes a presigned download URL for the report file if one has been validated.
177- /// If no file is associated, the response contains inline ReportData.
178178 /// </summary>
179179 /// <param name="organizationId">The unique identifier of the organization.</param>
180180 /// <param name="reportId">The unique identifier of the report to retrieve.</param>
@@ -227,7 +227,6 @@ public async Task<IActionResult> GetOrganizationReportAsync(Guid organizationId,
227227 /// <param name="request">The request model containing updated report data.</param>
228228 /// <returns>An <see cref="OrganizationReportResponseModel"/> with the updated report.</returns>
229229 [ HttpPatch ( "{organizationId}/{reportId}" ) ]
230- [ RequestSizeLimit ( Constants . FileSize501mb ) ]
231230 public async Task < IActionResult > UpdateOrganizationReportAsync (
232231 Guid organizationId ,
233232 Guid reportId ,
@@ -333,6 +332,9 @@ public async Task DeleteOrganizationReportAsync(Guid organizationId, Guid report
333332
334333 await _organizationReportRepo . DeleteAsync ( report ) ;
335334
335+ await _cache . RemoveByTagAsync (
336+ OrganizationReportCacheConstants . BuildCacheTagForOrganizationReports ( organizationId ) ) ;
337+
336338 if ( fileData != null && ! string . IsNullOrEmpty ( fileData . Id ) )
337339 {
338340 await _storageService . DeleteReportFilesAsync ( report , fileData . Id ) ;
@@ -497,6 +499,10 @@ await Request.GetFileAsync(async (stream) =>
497499 var ( valid , length ) = await _storageService . ValidateFileAsync ( report , fileData , minimum , maximum ) ;
498500 if ( ! valid )
499501 {
502+ await _storageService . DeleteReportFilesAsync ( report , fileData . Id ! ) ;
503+ await _organizationReportRepo . DeleteAsync ( report ) ;
504+ await _cache . RemoveByTagAsync (
505+ OrganizationReportCacheConstants . BuildCacheTagForOrganizationReports ( organizationId ) ) ;
500506 throw new BadRequestException ( "File received does not match expected constraints." ) ;
501507 }
502508
@@ -505,6 +511,8 @@ await Request.GetFileAsync(async (stream) =>
505511 report . SetReportFile ( fileData ) ;
506512 report . RevisionDate = DateTime . UtcNow ;
507513 await _organizationReportRepo . ReplaceAsync ( report ) ;
514+ await _cache . RemoveByTagAsync (
515+ OrganizationReportCacheConstants . BuildCacheTagForOrganizationReports ( organizationId ) ) ;
508516 }
509517
510518 /// <summary>
0 commit comments