Skip to content

Commit b8eb013

Browse files
authored
Merge pull request #6479 from NuGet/dev
[ReleasePrep][2018.25.09]RI of dev into master
2 parents 27c75ed + 2107f03 commit b8eb013

66 files changed

Lines changed: 2590 additions & 1186 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/NuGetGallery.Core/Auditing/AuditedAuthenticatedOperationAction.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public enum AuditedAuthenticatedOperationAction
2323
/// <summary>
2424
/// Login failed, user is an organization and should not have credentials.
2525
/// </summary>
26-
FailedLoginUserIsOrganization
26+
FailedLoginUserIsOrganization,
27+
28+
/// <summary>
29+
/// Symbol package push was attempted by a non-owner of the package
30+
/// </summary>
31+
SymbolsPackagePushAttemptByNonOwner
2732
}
2833
}

src/NuGetGallery.Core/Auditing/AuditedPackageAction.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public enum AuditedPackageAction
1515
Edit,
1616
[Obsolete("Undo package edit functionality is being retired.")]
1717
UndoEdit,
18-
Verify
18+
Verify,
19+
SymbolsCreate,
20+
SymbolsDelete
1921
}
2022
}

src/NuGetGallery.Core/CoreConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,7 @@ public static class CoreConstants
3939
public const string SymbolPackagesFolderName = "symbol-packages";
4040
public const string NuGetSymbolPackageFileExtension = ".snupkg";
4141
public const string SymbolPackageBackupsFolderName = "symbol-package-backups";
42+
43+
public const string UploadTracingKeyHeaderName = "upload-id";
4244
}
4345
}

src/NuGetGallery.Core/Infrastructure/TableErrorLog.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ public override string Log(Error error)
190190

191191
private void Obfuscate(Error error)
192192
{
193+
error.User = string.Empty;
194+
if (error.Form != null)
195+
{
196+
error.Form.Clear();
197+
}
198+
193199
//ServerVariables overrides requiring context from the http request should be handled in NuGetGallery.QuietLog
194200
var elmahException = error.Exception as ElmahException;
195201
if (elmahException != null)

src/NuGetGallery.Core/NuGetGallery.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
<Compile Include="Infrastructure\ElmahException.cs" />
169169
<Compile Include="Infrastructure\TableErrorLog.cs" />
170170
<Compile Include="Authentication\NuGetClaims.cs" />
171+
<Compile Include="PackageMetadataExtensions.cs" />
171172
<Compile Include="PackageReaderCoreExtensions.cs" />
172173
<Compile Include="PackageStatus.cs" />
173174
<Compile Include="Packaging\InvalidPackageException.cs" />
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using NuGetGallery.Packaging;
5+
using System.Linq;
6+
using ClientPackageType = NuGet.Packaging.Core.PackageType;
7+
8+
namespace NuGetGallery
9+
{
10+
/// <summary>
11+
/// Utilities extending PackageMetadata
12+
/// </summary>
13+
public static class PackageMetadataExtensions
14+
{
15+
private const string SymbolPackageTypeName = "SymbolsPackage";
16+
private static readonly ClientPackageType SymbolPackageType = new ClientPackageType(SymbolPackageTypeName, ClientPackageType.EmptyVersion);
17+
18+
/// <summary>
19+
/// The package is a symbol package, if and only if it has metadata
20+
/// element of type <see cref="SymbolPackageTypeName"/> and only that element in package types.
21+
/// </summary>
22+
/// <param name="metadata"><see cref="PackageMetadata"/> for package</param>
23+
/// <returns>True if the package is a symbols package</returns>
24+
public static bool IsSymbolPackage(this PackageMetadata metadata)
25+
{
26+
var packageTypes = metadata.GetPackageTypes();
27+
return packageTypes.Any()
28+
&& packageTypes.Count() == 1
29+
&& packageTypes.First() == SymbolPackageType;
30+
}
31+
}
32+
}

src/NuGetGallery.Core/Services/CoreMessageService.cs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,46 @@ [change your email notification settings]({emailSettingsUrl}).
7272
}
7373
}
7474

75+
public async Task SendSymbolPackageAddedNoticeAsync(SymbolPackage symbolPackage, string packageUrl, string packageSupportUrl, string emailSettingsUrl, IEnumerable<string> warningMessages = null)
76+
{
77+
bool hasWarnings = warningMessages != null && warningMessages.Any();
78+
79+
string subject;
80+
var warningMessagesPlaceholder = string.Empty;
81+
if (hasWarnings)
82+
{
83+
subject = $"[{CoreConfiguration.GalleryOwner.DisplayName}] Symbol package published with warnings - {symbolPackage.Id} {symbolPackage.Version}";
84+
warningMessagesPlaceholder = Environment.NewLine + string.Join(Environment.NewLine, warningMessages);
85+
}
86+
else
87+
{
88+
subject = $"[{CoreConfiguration.GalleryOwner.DisplayName}] Symbol package published - {symbolPackage.Id} {symbolPackage.Version}";
89+
}
90+
91+
string body = $@"The symbol package [{symbolPackage.Id} {symbolPackage.Version}]({packageUrl}) was recently published on {CoreConfiguration.GalleryOwner.DisplayName} by {symbolPackage.Package.User.Username}. If this was not intended, please [contact support]({packageSupportUrl}).
92+
{warningMessagesPlaceholder}
93+
94+
-----------------------------------------------
95+
<em style=""font-size: 0.8em;"">
96+
To stop receiving emails as an owner of this package, sign in to the {CoreConfiguration.GalleryOwner.DisplayName} and
97+
[change your email notification settings]({emailSettingsUrl}).
98+
</em>";
99+
100+
using (var mailMessage = new MailMessage())
101+
{
102+
mailMessage.Subject = subject;
103+
mailMessage.Body = body;
104+
mailMessage.From = CoreConfiguration.GalleryNoReplyAddress;
105+
106+
AddOwnersSubscribedToPackagePushedNotification(symbolPackage.Package.PackageRegistration, mailMessage);
107+
108+
if (mailMessage.To.Any())
109+
{
110+
await SendMessageAsync(mailMessage);
111+
}
112+
}
113+
}
114+
75115
public async Task SendPackageAddedWithWarningsNoticeAsync(Package package, string packageUrl, string packageSupportUrl, IEnumerable<string> warningMessages)
76116
{
77117
var subject = $"[{CoreConfiguration.GalleryOwner.DisplayName}] Package pushed with warnings - {package.PackageRegistration.Id} {package.Version}";
@@ -142,6 +182,52 @@ public async Task SendPackageValidationFailedNoticeAsync(Package package, Packag
142182
}
143183
}
144184

185+
public async Task SendSymbolPackageValidationFailedNoticeAsync(SymbolPackage symbolPackage, PackageValidationSet validationSet, string packageUrl, string packageSupportUrl, string announcementsUrl, string twitterUrl)
186+
{
187+
var validationIssues = validationSet.GetValidationIssues();
188+
189+
var subject = $"[{CoreConfiguration.GalleryOwner.DisplayName}] Symbol package validation failed - {symbolPackage.Id} {symbolPackage.Version}";
190+
var bodyBuilder = new StringBuilder();
191+
bodyBuilder.Append($@"The symbol package [{symbolPackage.Id} {symbolPackage.Version}]({packageUrl}) failed validation because of the following reason(s):
192+
");
193+
194+
foreach (var validationIssue in validationIssues)
195+
{
196+
bodyBuilder.Append($@"
197+
- {ParseValidationIssue(validationIssue, announcementsUrl, twitterUrl)}");
198+
}
199+
200+
bodyBuilder.Append($@"
201+
202+
Your symbol package was not published on {CoreConfiguration.GalleryOwner.DisplayName} and is not available for consumption.
203+
204+
");
205+
206+
if (validationIssues.Any(i => i.IssueCode == ValidationIssueCode.Unknown))
207+
{
208+
bodyBuilder.Append($"Please [contact support]({packageSupportUrl}) to help.");
209+
}
210+
else
211+
{
212+
var issuePluralString = validationIssues.Count() > 1 ? "all the issues" : "the issue";
213+
bodyBuilder.Append($"You can reupload your symbol package once you've fixed {issuePluralString} with it.");
214+
}
215+
216+
using (var mailMessage = new MailMessage())
217+
{
218+
mailMessage.Subject = subject;
219+
mailMessage.Body = bodyBuilder.ToString();
220+
mailMessage.From = CoreConfiguration.GalleryNoReplyAddress;
221+
222+
AddAllOwnersToMailMessage(symbolPackage.Package.PackageRegistration, mailMessage);
223+
224+
if (mailMessage.To.Any())
225+
{
226+
await SendMessageAsync(mailMessage);
227+
}
228+
}
229+
}
230+
145231
private static string ParseValidationIssue(ValidationIssue validationIssue, string announcementsUrl, string twitterUrl)
146232
{
147233
switch (validationIssue.IssueCode)
@@ -168,6 +254,10 @@ private static string ParseValidationIssue(ValidationIssue validationIssue, stri
168254
case ValidationIssueCode.PackageIsSignedWithUnauthorizedCertificate:
169255
var certIssue = (UnauthorizedCertificateFailure)validationIssue;
170256
return $"The package was signed, but the signing certificate {(certIssue != null ? $"(SHA-1 thumbprint {certIssue.Sha1Thumbprint})" : "")} is not associated with your account. You must register this certificate to publish signed packages. [Read more...](https://aka.ms/nuget-signed-ref)";
257+
case ValidationIssueCode.SymbolErrorCode_ChecksumDoesNotMatch:
258+
return "The checksum does not match for the dll(s) and corresponding pdb(s).";
259+
case ValidationIssueCode.SymbolErrorCode_MatchingPortablePDBNotFound:
260+
return "The uploaded symbols package contains pdb(s) for a corresponding dll(s) not found in the nuget package.";
171261
default:
172262
return "There was an unknown failure when validating your package.";
173263
}
@@ -210,6 +300,42 @@ public async Task SendValidationTakingTooLongNoticeAsync(Package package, string
210300
}
211301
}
212302

303+
public async Task SendValidationTakingTooLongNoticeAsync(SymbolPackage symbolPackage, string packageUrl)
304+
{
305+
string subject = "[{0}] Symbol package validation taking longer than expected - {1} {2}";
306+
string body = "It is taking longer than expected for your symbol package [{1} {2}]({3}) to get published.\n\n" +
307+
"We are looking into it and there is no action on you at this time. We’ll send you an email notification when your symbol package has been published.\n\n" +
308+
"Thank you for your patience.";
309+
310+
body = string.Format(
311+
CultureInfo.CurrentCulture,
312+
body,
313+
CoreConfiguration.GalleryOwner.DisplayName,
314+
symbolPackage.Id,
315+
symbolPackage.Version,
316+
packageUrl);
317+
318+
subject = string.Format(
319+
CultureInfo.CurrentCulture,
320+
subject,
321+
CoreConfiguration.GalleryOwner.DisplayName,
322+
symbolPackage.Id,
323+
symbolPackage.Version);
324+
325+
using (var mailMessage = new MailMessage())
326+
{
327+
mailMessage.Subject = subject;
328+
mailMessage.Body = body;
329+
mailMessage.From = CoreConfiguration.GalleryNoReplyAddress;
330+
331+
AddOwnersSubscribedToPackagePushedNotification(symbolPackage.Package.PackageRegistration, mailMessage);
332+
333+
if (mailMessage.To.Any())
334+
{
335+
await SendMessageAsync(mailMessage);
336+
}
337+
}
338+
}
213339

214340
protected static void AddAllOwnersToMailMessage(PackageRegistration packageRegistration, MailMessage mailMessage)
215341
{

src/NuGetGallery.Core/Services/ICoreMessageService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ public interface ICoreMessageService
1313
Task SendPackageAddedWithWarningsNoticeAsync(Package package, string packageUrl, string packageSupportUrl, IEnumerable<string> warningMessages);
1414
Task SendPackageValidationFailedNoticeAsync(Package package, PackageValidationSet validationSet, string packageUrl, string packageSupportUrl, string announcementsUrl, string twitterUrl);
1515
Task SendValidationTakingTooLongNoticeAsync(Package package, string packageUrl);
16+
Task SendValidationTakingTooLongNoticeAsync(SymbolPackage symbolPackage, string packageUrl);
17+
Task SendSymbolPackageAddedNoticeAsync(SymbolPackage symbolPackage, string packageUrl, string packageSupportUrl, string emailSettingsUrl, IEnumerable<string> warningMessages = null);
18+
Task SendSymbolPackageValidationFailedNoticeAsync(SymbolPackage symbolPackage, PackageValidationSet validationSet, string packageUrl, string packageSupportUrl, string announcementsUrl, string twitterUrl);
1619
}
1720
}

src/NuGetGallery.Core/StreamExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System.IO;
5-
using System.Threading.Tasks;
65

76
namespace NuGetGallery
87
{

src/NuGetGallery/App_Start/DefaultDependenciesModule.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ protected override void Load(ContainerBuilder builder)
323323
.As<ICertificateService>()
324324
.InstancePerLifetimeScope();
325325

326+
builder.RegisterType<TyposquattingService>()
327+
.AsSelf()
328+
.As<ITyposquattingService>()
329+
.InstancePerLifetimeScope();
330+
326331
Func<MailSender> mailSenderFactory = () =>
327332
{
328333
var settings = configuration;

0 commit comments

Comments
 (0)