Skip to content

Commit 5440553

Browse files
authored
Merge pull request #241 from AlexanderLanin/subdomain
Detect github.my-company-server.com as GitHub
2 parents c38fdc2 + 7d6b9c5 commit 5440553

File tree

2 files changed

+85
-35
lines changed

2 files changed

+85
-35
lines changed

src/shared/GitHub.Tests/GitHubHostProviderTests.cs

+47-24
Original file line numberDiff line numberDiff line change
@@ -28,46 +28,66 @@ public void GitHubHostProvider_IsGitHubDotCom(string input, bool expected)
2828
[Theory]
2929
// We report that we support unencrypted HTTP here so that we can fail and
3030
// show a helpful error message in the call to `GenerateCredentialAsync` instead.
31-
[InlineData("http://github.com", true)]
32-
[InlineData("http://gist.github.com", true)]
33-
[InlineData("https://github.com", true)]
34-
[InlineData("https://gist.github.com", true)]
35-
[InlineData("ssh://github.com", false)]
36-
[InlineData("https://example.com", false)]
37-
public void GitHubHostProvider_IsSupported(string uriString, bool expected)
31+
[InlineData("http", "github.com", true)]
32+
[InlineData("http", "gist.github.com", true)]
33+
[InlineData("ssh", "github.com", false)]
34+
[InlineData("https", "example.com", false)]
35+
36+
[InlineData("https", "github.com", true)]
37+
[InlineData("https", "github.con", false)] // No support of phony similar tld.
38+
[InlineData("https", "gist.github.con", false)] // No support of phony similar tld.
39+
[InlineData("https", "foogithub.jparrowsec.cn", false)] // No support of non github.com domains.
40+
[InlineData("https", "api.github.com", false)] // No support of github.com subdomains.
41+
[InlineData("https", "gist.github.com", true)] // Except gists.
42+
[InlineData("https", "GiST.github.com", true)]
43+
[InlineData("https", "github.com", true)]
44+
45+
[InlineData("http", "github.my-company-server.com", true)]
46+
[InlineData("http", "gist.github.my-company-server.com", true)]
47+
[InlineData("https", "github.my-company-server.com", true)]
48+
[InlineData("https", "gist.github.my-company-server.com", true)]
49+
[InlineData("https", "gist.my-company-server.com", false)]
50+
[InlineData("https", "my-company-server.com", false)]
51+
[InlineData("https", "github.my.company.server.com", true)]
52+
[InlineData("https", "foogithub.my-company-server.com", false)]
53+
[InlineData("https", "api.github.my-company-server.com", false)]
54+
[InlineData("https", "gist.github.my.company.server.com", true)]
55+
[InlineData("https", "GitHub.My-Company-Server.Com", true)]
56+
[InlineData("https", "GiST.GitHub.My-Company-Server.com", true)]
57+
public void GitHubHostProvider_IsSupported(string protocol, string host, bool expected)
3858
{
39-
Uri uri = new Uri(uriString);
40-
4159
var input = new InputArguments(new Dictionary<string, string>
4260
{
43-
["protocol"] = uri.Scheme,
44-
["host"] = uri.Host,
61+
["protocol"] = protocol,
62+
["host"] = host,
4563
});
4664

47-
// Ensure nothing got lost during transformation
48-
Assert.Equal(uriString, input.Protocol + "://" + input.Host);
49-
5065
var provider = new GitHubHostProvider(new TestCommandContext());
5166
Assert.Equal(expected, provider.IsSupported(input));
5267
}
5368

5469

5570
[Theory]
56-
[InlineData("https://github.com", "https://github.com")]
57-
[InlineData("https://gist.github.com", "https://github.com")]
58-
public void GitHubHostProvider_GetCredentialServiceUrl(string uriString, string expectedService)
71+
[InlineData("https", "github.com", "https://github.com")]
72+
[InlineData("https", "github.com", "https://github.com")]
73+
[InlineData("https", "gist.github.com", "https://github.com")]
74+
[InlineData("https", "GiST.github.com", "https://github.com")]
75+
[InlineData("https", "github.my-company-server.com", "https://github.my-company-server.com")]
76+
[InlineData("https", "GitHub.My-Company-Server.Com", "https://github.my-company-server.com")]
77+
[InlineData("https", "gist.github.my-company-server.com", "https://github.my-company-server.com")]
78+
[InlineData("https", "GiST.GitHub.My-Company-Server.Com", "https://github.my-company-server.com")]
79+
[InlineData("https", "github.my.company.server.com", "https://github.my.company.server.com")]
80+
[InlineData("https", "GitHub.My.Company.Server.Com", "https://github.my.company.server.com")]
81+
[InlineData("https", "gist.github.my.company.server.com", "https://github.my.company.server.com")]
82+
[InlineData("https", "GiST.GitHub.My.Company.Server.Com", "https://github.my.company.server.com")]
83+
public void GitHubHostProvider_GetCredentialServiceUrl(string protocol, string host, string expectedService)
5984
{
60-
Uri uri = new Uri(uriString);
61-
6285
var input = new InputArguments(new Dictionary<string, string>
6386
{
64-
["protocol"] = uri.Scheme,
65-
["host"] = uri.Host,
87+
["protocol"] = protocol,
88+
["host"] = host,
6689
});
6790

68-
// Ensure nothing got lost during transformation
69-
Assert.Equal(uriString, input.Protocol + "://" + input.Host);
70-
7191
var provider = new GitHubHostProvider(new TestCommandContext());
7292
Assert.Equal(expectedService, provider.GetServiceName(input));
7393
}
@@ -76,8 +96,11 @@ public void GitHubHostProvider_GetCredentialServiceUrl(string uriString, string
7696
[Theory]
7797
[InlineData("https://example.com", "oauth", AuthenticationModes.OAuth)]
7898
[InlineData("https://github.com", "NOT-A-REAL-VALUE", GitHubConstants.DotComAuthenticationModes)]
99+
[InlineData("https://github.com", "NOT-A-REAL-VALUE", GitHubConstants.DotComAuthenticationModes)]
79100
[InlineData("https://github.com", "none", GitHubConstants.DotComAuthenticationModes)]
101+
[InlineData("https://github.com", "none", GitHubConstants.DotComAuthenticationModes)]
80102
[InlineData("https://github.com", null, GitHubConstants.DotComAuthenticationModes)]
103+
[InlineData("https://github.com", null, GitHubConstants.DotComAuthenticationModes)]
81104
public async Task GitHubHostProvider_GetSupportedAuthenticationModes(string uriString, string gitHubAuthModes, AuthenticationModes expectedModes)
82105
{
83106
var targetUri = new Uri(uriString);

src/shared/GitHub/GitHubHostProvider.cs

+38-11
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,42 @@ public override bool IsSupported(InputArguments input)
5252
return false;
5353
}
5454

55-
// Split port number and hostname from host input argument
56-
input.TryGetHostAndPort(out string hostName, out _);
57-
5855
// We do not support unencrypted HTTP communications to GitHub,
5956
// but we report `true` here for HTTP so that we can show a helpful
6057
// error message for the user in `CreateCredentialAsync`.
61-
return (StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "http") ||
62-
StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "https")) &&
63-
(StringComparer.OrdinalIgnoreCase.Equals(hostName, GitHubConstants.GitHubBaseUrlHost) ||
64-
StringComparer.OrdinalIgnoreCase.Equals(hostName, GitHubConstants.GistBaseUrlHost));
58+
if (!StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "http") &&
59+
!StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "https"))
60+
{
61+
return false;
62+
}
63+
64+
// Split port number and hostname from host input argument
65+
input.TryGetHostAndPort(out string hostName, out _);
66+
67+
if (StringComparer.OrdinalIgnoreCase.Equals(hostName, GitHubConstants.GitHubBaseUrlHost) ||
68+
StringComparer.OrdinalIgnoreCase.Equals(hostName, GitHubConstants.GistBaseUrlHost))
69+
{
70+
return true;
71+
}
72+
73+
string[] domains = hostName.Split(new char[] { '.' });
74+
75+
// github[.subdomain].domain.tld
76+
if (domains.Length >= 3 &&
77+
StringComparer.OrdinalIgnoreCase.Equals(domains[0], "github"))
78+
{
79+
return true;
80+
}
81+
82+
// gist.github[.subdomain].domain.tld
83+
if (domains.Length >= 4 &&
84+
StringComparer.OrdinalIgnoreCase.Equals(domains[0], "gist") &&
85+
StringComparer.OrdinalIgnoreCase.Equals(domains[1], "github"))
86+
{
87+
return true;
88+
}
89+
90+
return false;
6591
}
6692

6793
public override string GetServiceName(InputArguments input)
@@ -264,10 +290,11 @@ private static Uri NormalizeUri(Uri uri)
264290
}
265291

266292
// Special case for gist.github.com which are git backed repositories under the hood.
267-
// Credentials for these repositories are the same as the one stored with "github.com"
268-
if (uri.DnsSafeHost.Equals(GitHubConstants.GistBaseUrlHost, StringComparison.OrdinalIgnoreCase))
269-
{
270-
return new Uri("https://" + GitHubConstants.GitHubBaseUrlHost);
293+
// Credentials for these repositories are the same as the one stored with "github.com".
294+
// Same for gist.github[.subdomain].domain.tld. The general form was already checked via IsSupported.
295+
int firstDot = uri.DnsSafeHost.IndexOf(".");
296+
if (firstDot > -1 && uri.DnsSafeHost.Substring(0, firstDot).Equals("gist", StringComparison.OrdinalIgnoreCase)) {
297+
return new Uri("https://" + uri.DnsSafeHost.Substring(firstDot+1));
271298
}
272299

273300
return uri;

0 commit comments

Comments
 (0)