Skip to content

Commit 16c912d

Browse files
authored
Transform Project Url scheme to HTTPs for known domains (#6398)
* Transform Project Url scheme to HTTPs for known domains * PR feedback
1 parent 3b705c6 commit 16c912d

6 files changed

Lines changed: 82 additions & 6 deletions

File tree

src/NuGetGallery/Helpers/PackageHelper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public static bool IsHttpsProtocol(this Uri uri)
3939
return uri.Scheme == Uri.UriSchemeHttps;
4040
}
4141

42+
public static bool IsHttpProtocol(this Uri uri)
43+
{
44+
return uri.Scheme == Uri.UriSchemeHttp;
45+
}
46+
4247
public static bool IsGitProtocol(this Uri uri)
4348
{
4449
return uri.Scheme == Constants.GitRepository;

src/NuGetGallery/ViewModels/DisplayPackageViewModel.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public DisplayPackageViewModel(Package package, User currentUser, string pushedB
5757
PushedBy = pushedBy;
5858

5959
InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);
60+
InitializeProjectUrl(package.ProjectUrl);
6061
}
6162

6263
public bool ValidatingTooLong { get; set; }
@@ -108,6 +109,7 @@ public bool HasNewerRelease
108109
public bool IsCertificatesUIEnabled { get; set; }
109110
public string RepositoryUrl { get; private set; }
110111
public RepositoryKind RepositoryType { get; private set; }
112+
public string ProjectUrl { get; set; }
111113

112114
private IDictionary<User, string> _pushedByCache = new Dictionary<User, string>();
113115

@@ -183,14 +185,54 @@ private void InitializeRepositoryMetadata(string repositoryUrl, string repositor
183185
}
184186
}
185187

186-
private bool IsGitHubUri(Uri uri)
188+
private void InitializeProjectUrl(string projectUrlString)
189+
{
190+
if (Uri.TryCreate(projectUrlString, UriKind.Absolute, out var projectUrl))
191+
{
192+
if (projectUrl.IsHttpProtocol() && IsDomainWithHttpsSupport(projectUrl))
193+
{
194+
var uri = new UriBuilder(projectUrl);
195+
uri.Scheme = Uri.UriSchemeHttps;
196+
uri.Port = -1;
197+
198+
ProjectUrl = uri.ToString();
199+
}
200+
else if (projectUrl.IsHttpsProtocol() || projectUrl.IsHttpProtocol())
201+
{
202+
ProjectUrl = projectUrl.ToString();
203+
}
204+
}
205+
}
206+
207+
private static bool IsDomainWithHttpsSupport(Uri uri)
208+
{
209+
return IsGitHubUri(uri) || IsCodeplexUri(uri) || IsMicrosoftUri(uri);
210+
}
211+
212+
private static bool IsGitHubUri(Uri uri)
187213
{
188214
return string.Equals(uri.Authority, "www.github.com", StringComparison.OrdinalIgnoreCase) ||
189215
string.Equals(uri.Authority, "github.com", StringComparison.OrdinalIgnoreCase) ||
190216
string.Equals(uri.Authority, "www.github.com:443", StringComparison.OrdinalIgnoreCase) ||
191217
string.Equals(uri.Authority, "github.com:443", StringComparison.OrdinalIgnoreCase);
192218
}
193219

220+
private static bool IsCodeplexUri(Uri uri)
221+
{
222+
return uri.Authority.EndsWith(".codeplex.com", StringComparison.OrdinalIgnoreCase) ||
223+
string.Equals(uri.Authority, "codeplex.com", StringComparison.OrdinalIgnoreCase);
224+
}
225+
226+
private static bool IsMicrosoftUri(Uri uri)
227+
{
228+
return uri.Authority.EndsWith(".microsoft.com", StringComparison.OrdinalIgnoreCase) ||
229+
string.Equals(uri.Authority, "microsoft.com", StringComparison.OrdinalIgnoreCase) ||
230+
string.Equals(uri.Authority, "www.asp.net", StringComparison.OrdinalIgnoreCase) ||
231+
string.Equals(uri.Authority, "asp.net", StringComparison.OrdinalIgnoreCase) ||
232+
uri.Authority.EndsWith(".msdn.com", StringComparison.OrdinalIgnoreCase) ||
233+
string.Equals(uri.Authority, "msdn.com", StringComparison.OrdinalIgnoreCase);
234+
}
235+
194236
public enum RepositoryKind
195237
{
196238
Unknown,

src/NuGetGallery/ViewModels/ManagePackageOwnersViewModel.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
using System.Security.Principal;
5-
64
namespace NuGetGallery
75
{
86
public class ManagePackageOwnersViewModel : ListPackageItemViewModel

src/NuGetGallery/ViewModels/PackageViewModel.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public PackageViewModel(Package package)
3232
Description = package.Description;
3333
ReleaseNotes = package.ReleaseNotes;
3434
IconUrl = package.IconUrl;
35-
ProjectUrl = package.ProjectUrl;
3635
LicenseUrl = package.LicenseUrl;
3736
HideLicenseReport = package.HideLicenseReport;
3837
LatestVersion = package.IsLatest;
@@ -56,7 +55,6 @@ public PackageViewModel(Package package)
5655
public string Description { get; set; }
5756
public string ReleaseNotes { get; set; }
5857
public string IconUrl { get; set; }
59-
public string ProjectUrl { get; set; }
6058
public string LicenseUrl { get; set; }
6159
public Boolean HideLicenseReport { get; set; }
6260
public IEnumerable<string> LicenseNames { get; set; }

src/NuGetGallery/Views/Packages/DisplayPackage.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@
539539
<i class="ms-Icon ms-Icon--History" aria-hidden="true"></i>
540540
last updated <span data-datetime="@Model.LastUpdated.ToString("O")">@Model.LastUpdated.ToNuGetShortDateString()</span>
541541
</li>
542-
@if (!Model.Deleted && PackageHelper.ShouldRenderUrl(Model.ProjectUrl))
542+
@if (!Model.Deleted && Model.ProjectUrl != null)
543543
{
544544
<li>
545545
<i class="ms-Icon ms-Icon--Globe" aria-hidden="true"></i>

tests/NuGetGallery.Facts/ViewModels/DisplayPackageViewModelFacts.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,39 @@ public void ItDeterminesRepositoryKind(string repoUrl, string repoType, Reposito
5555
Assert.Equal(expectedUrl, model.RepositoryUrl);
5656
}
5757

58+
[Theory]
59+
[InlineData(null, null)]
60+
[InlineData("", null)]
61+
[InlineData("not a url", null)]
62+
[InlineData("git://github.com/notavalidscheme", null)]
63+
[InlineData("https://github.com/nuget", "https://github.com/nuget")]
64+
[InlineData("https://anydomain.com:443/abc/q?stuff", "https://anydomain.com/abc/q?stuff")]
65+
[InlineData("http://github.com/nuget", "https://github.com/nuget")]
66+
[InlineData("http://www.github.com/nuget", "https://www.github.com/nuget")]
67+
[InlineData("http://www.github.com:443/nuget", "https://www.github.com/nuget")]
68+
[InlineData("http://aspnetwebstack.codeplex.com/license", "https://aspnetwebstack.codeplex.com/license")]
69+
[InlineData("http://codeplex.com", "https://codeplex.com/")]
70+
[InlineData("http://www.codeplex.com", "https://www.codeplex.com/")]
71+
[InlineData("http://www.microsoft.com/web/webpi/eula/aspnetcomponent_enu.htm", "https://www.microsoft.com/web/webpi/eula/aspnetcomponent_enu.htm")]
72+
[InlineData("http://go.microsoft.com/?linkid=9809688", "https://go.microsoft.com/?linkid=9809688")]
73+
[InlineData("http://www.asp.net/web-pages", "https://www.asp.net/web-pages")]
74+
[InlineData("http://blogs.msdn.com/b/bclteam/p/asynctargetingpackkb.aspx", "https://blogs.msdn.com/b/bclteam/p/asynctargetingpackkb.aspx")]
75+
[InlineData("http://msdn.com", "https://msdn.com/")]
76+
[InlineData("http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx", "https://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx")]
77+
[InlineData("http://microsoft.com/iconurl/9594202", "https://microsoft.com/iconurl/9594202")]
78+
[InlineData("http://microsoft.com:80/", "https://microsoft.com/")]
79+
public void ItInitializesProjectUrl(string projectUrl, string expected)
80+
{
81+
var package = new Package
82+
{
83+
Version = "1.0.0",
84+
ProjectUrl = projectUrl
85+
};
86+
87+
var model = new DisplayPackageViewModel(package, null, "test");
88+
Assert.Equal(expected, model.ProjectUrl);
89+
}
90+
5891
[Fact]
5992
public void TheCtorSortsPackageVersionsProperly()
6093
{

0 commit comments

Comments
 (0)