forked from NuGet/NuGetGallery
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tool to determine if a .nupkg has valid Microsoft metadata (NuGet…
…#7834) New version of NuGet#7000
- Loading branch information
1 parent
62eb1e4
commit 4ac9939
Showing
22 changed files
with
1,924 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/NuGetGallery.Services/Security/RequirePackageMetadataComplianceUtility.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
using Newtonsoft.Json; | ||
using NuGet.Services.Entities; | ||
|
||
namespace NuGetGallery.Security | ||
{ | ||
public static class RequirePackageMetadataComplianceUtility | ||
{ | ||
/// <summary> | ||
/// Retrieve the policy state. | ||
/// </summary> | ||
public static RequirePackageMetadataState DeserializeState(IEnumerable<UserSecurityPolicy> policies) | ||
{ | ||
var policyStates = policies | ||
.Where(p => !string.IsNullOrEmpty(p.Value)) | ||
.Select(p => JsonConvert.DeserializeObject<RequirePackageMetadataState>(p.Value)); | ||
|
||
// TODO: what if there are multiple? | ||
return policyStates.First(); | ||
} | ||
|
||
public static bool IsPackageMetadataCompliant(Package package, RequirePackageMetadataState state, out IList<string> complianceFailures) | ||
{ | ||
complianceFailures = new List<string>(); | ||
|
||
// Author validation | ||
ValidatePackageAuthors(package, state, complianceFailures); | ||
|
||
// Copyright validation | ||
if (!state.AllowedCopyrightNotices.Contains(package.Copyright)) | ||
{ | ||
complianceFailures.Add(ServicesStrings.SecurityPolicy_CopyrightNotCompliant); | ||
} | ||
|
||
// LicenseUrl validation | ||
if (state.IsLicenseUrlRequired && string.IsNullOrWhiteSpace(package.LicenseUrl)) | ||
{ | ||
complianceFailures.Add(ServicesStrings.SecurityPolicy_RequiredLicenseUrlMissing); | ||
} | ||
|
||
// ProjectUrl validation | ||
if (state.IsProjectUrlRequired && string.IsNullOrWhiteSpace(package.ProjectUrl)) | ||
{ | ||
complianceFailures.Add(ServicesStrings.SecurityPolicy_RequiredProjectUrlMissing); | ||
} | ||
|
||
return !complianceFailures.Any(); | ||
} | ||
|
||
private static void ValidatePackageAuthors(Package package, RequirePackageMetadataState state, IList<string> complianceFailures) | ||
{ | ||
var packageAuthors = package.FlattenedAuthors | ||
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) | ||
.Select(s => s.Trim()) | ||
.ToList(); | ||
|
||
// Check for duplicate entries | ||
var duplicateAuthors = packageAuthors | ||
.GroupBy(x => x) | ||
.Where(group => group.Count() > 1) | ||
.Select(group => group.Key) | ||
.ToList(); | ||
|
||
if (duplicateAuthors.Any()) | ||
{ | ||
complianceFailures.Add(string.Format(CultureInfo.CurrentCulture, ServicesStrings.SecurityPolicy_PackageAuthorDuplicatesNotAllowed, string.Join(",", duplicateAuthors))); | ||
} | ||
else | ||
{ | ||
if (state.AllowedAuthors?.Length > 0) | ||
{ | ||
foreach (var packageAuthor in packageAuthors) | ||
{ | ||
if (!state.AllowedAuthors.Contains(packageAuthor)) | ||
{ | ||
complianceFailures.Add(string.Format(CultureInfo.CurrentCulture, ServicesStrings.SecurityPolicy_PackageAuthorNotAllowed, packageAuthor)); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
// No list of allowed authors is defined for this policy. | ||
// We require the required co-owner to be defined as the only package author. | ||
if (packageAuthors.Count() > 1 || packageAuthors.Single() != state.RequiredCoOwnerUsername) | ||
{ | ||
complianceFailures.Add(string.Format(CultureInfo.CurrentCulture, ServicesStrings.SecurityPolicy_RequiredAuthorMissing, state.RequiredCoOwnerUsername)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/NuGetGallery.Services/Security/RequirePackageMetadataState.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace NuGetGallery.Security | ||
{ | ||
public class RequirePackageMetadataState | ||
{ | ||
[JsonProperty("u")] | ||
public string RequiredCoOwnerUsername { get; set; } | ||
|
||
[JsonProperty("copy")] | ||
public string[] AllowedCopyrightNotices { get; set; } | ||
|
||
[JsonProperty("authors")] | ||
public string[] AllowedAuthors { get; set; } | ||
|
||
[JsonProperty("licUrlReq")] | ||
public bool IsLicenseUrlRequired { get; set; } | ||
|
||
[JsonProperty("projUrlReq")] | ||
public bool IsProjectUrlRequired { get; set; } | ||
|
||
[JsonProperty("error")] | ||
public string ErrorMessageFormat { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/> | ||
</startup> | ||
</configuration> |
Oops, something went wrong.