Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Commit 41d163c

Browse files
authored
Add cache control on blobs in public containers (#663)
1 parent 8f331cb commit 41d163c

8 files changed

Lines changed: 65 additions & 38 deletions

File tree

src/NuGet.Services.Validation.Orchestrator/IValidationPackageFileService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ Task CopyValidationSetPackageToPackageFileAsync(
124124
/// successive read and write operations.</exception>
125125
Task<PackageStreamMetadata> UpdatePackageBlobMetadataAsync(PackageValidationSet validationSet);
126126

127+
/// <summary>
128+
/// Updates package blob properties.
129+
/// </summary>
130+
/// <param name="validationSet">A validationSet that will identify the package that will have its blob metadata updated.</param>
131+
/// <exception cref="Microsoft.WindowsAzure.Storage.StorageException">Thrown if the blob has changed between
132+
/// successive read and write operations.</exception>
133+
Task UpdatePackageBlobPropertiesAsync(PackageValidationSet validationSet);
134+
127135
/// <summary>
128136
/// Reads the ETag for the package in the public container.
129137
/// </summary>

src/NuGet.Services.Validation.Orchestrator/PackageStatusProcessor.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,16 @@ protected virtual async Task MakePackageAvailableAsync(IValidatingEntity<T> vali
9494
// 1) Operate on blob storage.
9595
var copied = await UpdatePublicPackageAsync(validationSet);
9696

97-
// 2) Update the package's blob metadata in the packages blob storage container.
97+
// 2) Update the package's blob metadata in the public blob storage container.
9898
var metadata = await _packageFileService.UpdatePackageBlobMetadataAsync(validationSet);
9999

100-
// 3) Operate on the database.
100+
// 3) Update the package's blob properties in the public blob storage container.
101+
await _packageFileService.UpdatePackageBlobPropertiesAsync(validationSet);
102+
103+
// 4) Operate on the database.
101104
var fromStatus = await MarkPackageAsAvailableAsync(validationSet, validatingEntity, metadata, copied);
102105

103-
// 4) Emit telemetry and clean up.
106+
// 5) Emit telemetry and clean up.
104107
if (fromStatus != PackageStatus.Available)
105108
{
106109
_telemetryService.TrackPackageStatusChange(fromStatus, PackageStatus.Available);
@@ -113,7 +116,7 @@ protected virtual async Task MakePackageAvailableAsync(IValidatingEntity<T> vali
113116
await _packageFileService.DeleteValidationPackageFileAsync(validationSet);
114117
}
115118

116-
// 4) Verify the package still exists (we've had bugs here before).
119+
// 5) Verify the package still exists (we've had bugs here before).
117120
if (validatingEntity.Status == PackageStatus.Available
118121
&& !await _packageFileService.DoesPackageFileExistAsync(validationSet))
119122
{

src/NuGet.Services.Validation.Orchestrator/ValidationPackageFileService.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,30 @@ public Task CopyPackageUrlForValidationSetAsync(PackageValidationSet validationS
223223
AccessConditionWrapper.GenerateEmptyCondition());
224224
}
225225

226+
public async Task UpdatePackageBlobPropertiesAsync(PackageValidationSet validationSet)
227+
{
228+
var fileName = BuildFileName(
229+
validationSet,
230+
_fileMetadataService.FileSavePathTemplate,
231+
_fileMetadataService.FileExtension);
232+
233+
// This will throw if the ETag changes between read and write operations.
234+
await _fileStorageService.SetPropertiesAsync(
235+
_fileMetadataService.FileFolderName,
236+
fileName,
237+
async (lazyStream, blobProperties) =>
238+
{
239+
// Update the cache control only if the cache control is not the same as the default value.
240+
if (!string.Equals(blobProperties.CacheControl, CoreConstants.DefaultCacheControl, StringComparison.OrdinalIgnoreCase))
241+
{
242+
blobProperties.CacheControl = CoreConstants.DefaultCacheControl;
243+
return await Task.FromResult(true);
244+
}
245+
246+
return await Task.FromResult(false);
247+
});
248+
}
249+
226250
public async Task<PackageStreamMetadata> UpdatePackageBlobMetadataAsync(PackageValidationSet validationSet)
227251
{
228252
var fileName = BuildFileName(

src/Validation.Common.Job/Validation.Common.Job.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
<Version>2.33.0</Version>
104104
</PackageReference>
105105
<PackageReference Include="NuGetGallery.Core">
106-
<Version>4.4.5-dev-2170472</Version>
106+
<Version>4.4.5-dev-2193892</Version>
107107
</PackageReference>
108108
<PackageReference Include="Serilog">
109109
<Version>2.5.0</Version>

src/Validation.PackageSigning.ProcessSignature/SignatureFormatValidator.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,10 @@ public class SignatureFormatValidator : ISignatureFormatValidator
2323
allowNoTimestamp: true,
2424
allowUnknownRevocation: true,
2525
reportUnknownRevocation: false,
26-
allowNoRepositoryCertificateList: true,
27-
allowNoClientCertificateList: true,
2826
verificationTarget: VerificationTarget.All,
2927
signaturePlacement: SignaturePlacement.PrimarySignature,
3028
repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.Never,
31-
repoAllowListEntries: null,
32-
clientAllowListEntries: null);
29+
revocationMode: RevocationMode.Online);
3330

3431
private static readonly PackageSignatureVerifier _minimalVerifier = new PackageSignatureVerifier(new[]
3532
{
@@ -40,7 +37,7 @@ public class SignatureFormatValidator : ISignatureFormatValidator
4037
{
4138
new IntegrityVerificationProvider(),
4239
new SignatureTrustAndValidityVerificationProvider(),
43-
new AllowListVerificationProvider(),
40+
new AllowListVerificationProvider(allowList: null),
4441
});
4542

4643
private readonly IOptionsSnapshot<ProcessSignatureConfiguration> _config;
@@ -61,13 +58,10 @@ public SignatureFormatValidator(IOptionsSnapshot<ProcessSignatureConfiguration>
6158
allowNoTimestamp: false,
6259
allowUnknownRevocation: true,
6360
reportUnknownRevocation: true,
64-
allowNoRepositoryCertificateList: true,
65-
allowNoClientCertificateList: true,
6661
verificationTarget: VerificationTarget.Author,
6762
signaturePlacement: SignaturePlacement.PrimarySignature,
6863
repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.Never,
69-
repoAllowListEntries: null,
70-
clientAllowListEntries: null);
64+
revocationMode: RevocationMode.Online);
7165

7266
var repoAllowListEntries = _config
7367
.Value
@@ -90,13 +84,10 @@ public SignatureFormatValidator(IOptionsSnapshot<ProcessSignatureConfiguration>
9084
allowNoTimestamp: _authorSignatureSettings.AllowNoTimestamp,
9185
allowUnknownRevocation: _authorSignatureSettings.AllowUnknownRevocation,
9286
reportUnknownRevocation: _authorSignatureSettings.ReportUnknownRevocation,
93-
allowNoRepositoryCertificateList: false,
94-
allowNoClientCertificateList: _authorSignatureSettings.AllowNoClientCertificateList,
9587
verificationTarget: VerificationTarget.Repository,
9688
signaturePlacement: SignaturePlacement.Any,
9789
repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.IfExists,
98-
repoAllowListEntries: repoAllowListEntries,
99-
clientAllowListEntries: _authorSignatureSettings.ClientCertificateList);
90+
revocationMode: _authorSignatureSettings.RevocationMode);
10091

10192
_authorOrRepositorySignatureSettings = new SignedPackageVerifierSettings(
10293
allowUnsigned: _authorSignatureSettings.AllowUnsigned,
@@ -107,13 +98,10 @@ public SignatureFormatValidator(IOptionsSnapshot<ProcessSignatureConfiguration>
10798
allowNoTimestamp: _authorSignatureSettings.AllowNoTimestamp,
10899
allowUnknownRevocation: _authorSignatureSettings.AllowUnknownRevocation,
109100
reportUnknownRevocation: _authorSignatureSettings.ReportUnknownRevocation,
110-
allowNoRepositoryCertificateList: false,
111-
allowNoClientCertificateList: _authorSignatureSettings.AllowNoClientCertificateList,
112101
verificationTarget: VerificationTarget.All,
113102
signaturePlacement: SignaturePlacement.Any,
114103
repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.IfExists,
115-
repoAllowListEntries: repoAllowListEntries,
116-
clientAllowListEntries: _authorSignatureSettings.ClientCertificateList);
104+
revocationMode: _authorSignatureSettings.RevocationMode);
117105
}
118106

119107
public async Task<VerifySignaturesResult> ValidateMinimalAsync(

src/Validation.PackageSigning.ProcessSignature/SignatureValidator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ private async Task<bool> IsValidRepositorySignatureAsync<T>(Context context, T s
436436
// Strip repository signatures that do not pass verification.
437437
var verifyResult = await _formatValidator.ValidateRepositorySignatureAsync(context.PackageReader, context.CancellationToken);
438438

439-
if (!verifyResult.Valid)
439+
if (!verifyResult.IsValid)
440440
{
441441
var warningsForLogs = verifyResult
442442
.Results
@@ -654,7 +654,7 @@ private async Task<SignatureValidatorResult> GetVerifyResult(
654654
.Select(x => $"{x.Code}: {x.Message}")
655655
.ToList();
656656

657-
if (!verifyResult.Valid)
657+
if (!verifyResult.IsValid)
658658
{
659659
_logger.LogInformation(
660660
"Signed package {PackageId} {PackageVersion} is blocked during {VerificationName} for validation " +

tests/Validation.PackageSigning.ProcessSignature.Tests/SignatureValidatorFacts.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ public ValidateAsync(ITestOutputHelper output)
6363
_packageSigningStateService = new Mock<IPackageSigningStateService>();
6464
_formatValidator = new Mock<ISignatureFormatValidator>();
6565

66-
_minimalVerifyResult = new VerifySignaturesResult(valid: true, signed: true);
66+
_minimalVerifyResult = new VerifySignaturesResult(isValid: true, isSigned: true);
6767
_formatValidator
6868
.Setup(x => x.ValidateMinimalAsync(It.IsAny<ISignedPackageReader>(), It.IsAny<CancellationToken>()))
6969
.ReturnsAsync(() => _minimalVerifyResult);
7070

71-
_fullVerifyResult = new VerifySignaturesResult(valid: true, signed: true);
71+
_fullVerifyResult = new VerifySignaturesResult(isValid: true, isSigned: true);
7272
_formatValidator
7373
.Setup(x => x.ValidateAllSignaturesAsync(It.IsAny<ISignedPackageReader>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
7474
.ReturnsAsync(() => _fullVerifyResult);
@@ -276,7 +276,7 @@ public async Task RejectsSignedPackagesWithFailedMinimalVerifyResult()
276276
{
277277
// Arrange
278278
_packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
279-
_minimalVerifyResult = new VerifySignaturesResult(valid: false, signed: true);
279+
_minimalVerifyResult = new VerifySignaturesResult(isValid: false, isSigned: true);
280280
_message = new SignatureValidationMessage(
281281
TestResources.SignedPackageLeafId,
282282
TestResources.SignedPackageLeaf1Version,
@@ -304,8 +304,8 @@ public async Task RejectsPackagesWithMimimalVerificationErrors()
304304
// Arrange
305305
_packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
306306
_minimalVerifyResult = new VerifySignaturesResult(
307-
valid: false,
308-
signed: true,
307+
isValid: false,
308+
isSigned: true,
309309
results: new[]
310310
{
311311
new InvalidSignaturePackageVerificationResult(
@@ -349,7 +349,7 @@ public async Task RejectsSignedPackagesWithKnownCertificatesButFailedFullVerifyR
349349
TestResources.SignedPackageLeafId,
350350
TestResources.SignedPackageLeaf1Version,
351351
TestResources.Leaf1Thumbprint);
352-
_fullVerifyResult = new VerifySignaturesResult(valid: false, signed: true);
352+
_fullVerifyResult = new VerifySignaturesResult(isValid: false, isSigned: true);
353353
_message = new SignatureValidationMessage(
354354
TestResources.SignedPackageLeafId,
355355
TestResources.SignedPackageLeaf1Version,
@@ -379,8 +379,8 @@ public async Task RejectsPackagesWithFullVerificationErrors()
379379
TestResources.SignedPackageLeaf1Version,
380380
TestResources.Leaf1Thumbprint);
381381
_fullVerifyResult = new VerifySignaturesResult(
382-
valid: false,
383-
signed: true,
382+
isValid: false,
383+
isSigned: true,
384384
results: new[]
385385
{
386386
new InvalidSignaturePackageVerificationResult(

tests/Validation.PackageSigning.ProcessSignature.Tests/SignatureValidatorIntegrationTests.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,21 @@ public class SignatureValidatorIntegrationTests : IDisposable
4343
private const string AuthorPrimaryCertificateUntrustedMessage = "The author primary signature found a chain building issue: " +
4444
"A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.";
4545
private const string AuthorPrimaryCertificateRevocationOfflineMessage = "NU3018: The author primary signature found a chain building issue: " +
46-
"The revocation function was unable to check revocation because the revocation server was offline.";
46+
"The revocation function was unable to check revocation because the revocation server could not be reached.";
4747
private const string AuthorPrimaryCertificateRevocationUnknownMessage = "NU3018: The author primary signature found a chain building issue: " +
4848
"The revocation function was unable to check revocation for the certificate.";
4949
private const string RepositoryCounterCertificateRevocationOfflineMessage = "NU3018: The repository countersignature found a chain building issue: " +
50-
"The revocation function was unable to check revocation because the revocation server was offline.";
50+
"The revocation function was unable to check revocation because the revocation server could not be reached.";
5151
private const string RepositoryCounterCertificateRevocationUnknownMessage = "NU3018: The repository countersignature found a chain building issue: " +
5252
"The revocation function was unable to check revocation for the certificate.";
5353

54-
// NU3028
54+
// Should be NU3028 => TODO: https://github.com/NuGet/Engineering/issues/1891
5555
private const string AuthorPrimaryTimestampCertificateUntrustedMessage = "The author primary signature's timestamp found a chain building issue: " +
5656
"A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.";
57-
private const string AuthorPrimaryTimestampCertificateRevocationUnknownMessage = "NU3028: The author primary signature's timestamp found a chain building issue: " +
57+
private const string AuthorPrimaryTimestampCertificateRevocationUnknownMessage = "NU3018: The author primary signature's timestamp found a chain building issue: " +
5858
"The revocation function was unable to check revocation for the certificate.";
59-
private const string AuthorPrimaryTimestampCertificateRevocationOfflineMessage = "NU3028: The author primary signature's timestamp found a chain building issue: " +
60-
"The revocation function was unable to check revocation because the revocation server was offline.";
59+
private const string AuthorPrimaryTimestampCertificateRevocationOfflineMessage = "NU3018: The author primary signature's timestamp found a chain building issue: " +
60+
"The revocation function was unable to check revocation because the revocation server could not be reached.";
6161

6262
private readonly CertificateIntegrationTestFixture _fixture;
6363
private readonly ITestOutputHelper _output;
@@ -307,6 +307,7 @@ await _fixture.GetSigningCertificateAsync(),
307307
}
308308

309309
[Fact]
310+
// TODO: https://github.com/NuGet/Engineering/issues/1891
310311
public async Task AcceptsTrustedTimestampingCertificateWithUnavailableRevocation()
311312
{
312313
// Arrange
@@ -360,6 +361,7 @@ await _fixture.GetSigningCertificateAsync(),
360361
}
361362

362363
[Fact]
364+
// TODO: https://github.com/NuGet/Engineering/issues/1891
363365
public async Task AcceptsTrustedSigningCertificateWithUnavailableRevocation()
364366
{
365367
// Arrange
@@ -1449,6 +1451,7 @@ await _fixture.GetSigningCertificateAsync(),
14491451
}
14501452

14511453
[Fact]
1454+
// TODO: https://github.com/NuGet/Engineering/issues/1891
14521455
public async Task WhenRepositoryCounterSigned_AcceptsTrustedTimestampingCertificateWithUnavailableRevocation()
14531456
{
14541457
// Arrange
@@ -1508,6 +1511,7 @@ await _fixture.GetSigningCertificateAsync(),
15081511
}
15091512

15101513
[Fact]
1514+
// TODO: https://github.com/NuGet/Engineering/issues/1891
15111515
public async Task WhenRepositoryCounterSigned_AcceptsTrustedSigningCertificateWithUnavailableRevocation()
15121516
{
15131517
// Arrange

0 commit comments

Comments
 (0)