diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHelperTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHelperTest.cs index cad371431..b2bae24aa 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHelperTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHelperTest.cs @@ -1,3 +1,6 @@ +using Atlassian.Bitbucket.DataCenter; +using GitCredentialManager; +using Moq; using System; using Xunit; @@ -5,6 +8,10 @@ namespace Atlassian.Bitbucket.Tests { public class BitbucketHelperTest { + + + private Mock settings = new Mock(MockBehavior.Loose); + [Theory] [InlineData(null, false)] [InlineData("", false)] @@ -56,5 +63,36 @@ public void BitbucketHelper_IsBitbucketOrg_Uri(string str, bool expected) bool actual = BitbucketHelper.IsBitbucketOrg(new Uri(str)); Assert.Equal(expected, actual); } + + [Theory] + // old behavior + [InlineData("http://bitbucket.org", null, "http://bitbucket.org:80")] + [InlineData("https://bitbucket.org", null, "https://bitbucket.org:443")] + [InlineData("https://bitbucket.org/project/repo.git", null, "https://bitbucket.org:443/project")] + // with http path + [InlineData("http://bitbucket.org", "/bitbucket", "http://bitbucket.org:80/bitbucket")] + [InlineData("https://bitbucket.org", "/bitbucket", "https://bitbucket.org:443/bitbucket")] + // usehttppath takes preference over httpPath + [InlineData("https://bitbucket.org/project/repo.git", "/bitbucket", "https://bitbucket.org:443/project")] + public void BitbucketHelper_GetBaseUri(string uri, string httpPath, string expected) + { + + settings.Setup(s => s.RemoteUri).Returns(new Uri(uri)); + if(httpPath != null) + { + MockHttpPath(httpPath); + } + var actual = BitbucketHelper.GetBaseUri(settings.Object); + Assert.Equal(expected, actual); + } + + private string MockHttpPath(string value) + { + settings.Setup(s => s.TryGetSetting( + DataCenterConstants.EnvironmentVariables.HttpPath, + Constants.GitConfiguration.Credential.SectionName, DataCenterConstants.GitConfiguration.Credential.HttpPath, + out value)).Returns(true); + return value; + } } } \ No newline at end of file diff --git a/src/shared/Atlassian.Bitbucket/BitbucketHelper.cs b/src/shared/Atlassian.Bitbucket/BitbucketHelper.cs index 3624627f0..42defcfef 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketHelper.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketHelper.cs @@ -1,17 +1,38 @@ using System; using Atlassian.Bitbucket.Cloud; +using Atlassian.Bitbucket.DataCenter; using GitCredentialManager; namespace Atlassian.Bitbucket { public static class BitbucketHelper { - public static string GetBaseUri(Uri remoteUri) + + private static bool TryGetHttpPath(ISettings settings, out string httpPath) + { + return settings.TryGetSetting( + DataCenterConstants.EnvironmentVariables.HttpPath, + Constants.GitConfiguration.Credential.SectionName, DataCenterConstants.GitConfiguration.Credential.HttpPath, + out httpPath); + } + + public static string GetBaseUri(ISettings settings) { + var remoteUri = settings?.RemoteUri; + if (remoteUri == null) + { + throw new ArgumentException("RemoteUri must be defined to generate Bitbucket DC Rest/OAuth endpoints"); + } + var pathParts = remoteUri.PathAndQuery.Split('/'); var pathPart = remoteUri.PathAndQuery.StartsWith("/") ? pathParts[1] : pathParts[0]; var path = !string.IsNullOrWhiteSpace(pathPart) ? "/" + pathPart : null; + if(path == null && TryGetHttpPath(settings, out string httpPath) && !string.IsNullOrEmpty(httpPath)) + { + path = httpPath; + } return $"{remoteUri.Scheme}://{remoteUri.Host}:{remoteUri.Port}{path}"; + } public static bool IsBitbucketOrg(InputArguments input) diff --git a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketOAuth2Client.cs b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketOAuth2Client.cs index 97abd533c..e764a7558 100644 --- a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketOAuth2Client.cs +++ b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketOAuth2Client.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; using GitCredentialManager; using GitCredentialManager.Authentication.OAuth; @@ -68,15 +66,9 @@ private static string GetClientSecret(ISettings settings) private static OAuth2ServerEndpoints GetEndpoints(ISettings settings) { - var remoteUri = settings.RemoteUri; - if (remoteUri == null) - { - throw new ArgumentException("RemoteUri must be defined to generate Bitbucket DC OAuth2 endpoint Urls"); - } - return new OAuth2ServerEndpoints( - new Uri(BitbucketHelper.GetBaseUri(remoteUri) + "/rest/oauth2/latest/authorize"), - new Uri(BitbucketHelper.GetBaseUri(remoteUri) + "/rest/oauth2/latest/token") + new Uri(BitbucketHelper.GetBaseUri(settings) + "/rest/oauth2/latest/authorize"), + new Uri(BitbucketHelper.GetBaseUri(settings) + "/rest/oauth2/latest/token") ); } } diff --git a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs index 159229885..19e8ad929 100644 --- a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs +++ b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs @@ -141,13 +141,7 @@ private Uri ApiUri { get { - var remoteUri = _context.Settings?.RemoteUri; - if (remoteUri == null) - { - throw new ArgumentException("RemoteUri must be defined to generate Bitbucket DC OAuth2 endpoint Urls"); - } - - return new Uri(BitbucketHelper.GetBaseUri(remoteUri) + "/rest/"); + return new Uri(BitbucketHelper.GetBaseUri(_context.Settings) + "/rest/"); } } } diff --git a/src/shared/Atlassian.Bitbucket/DataCenter/DataCenterConstants.cs b/src/shared/Atlassian.Bitbucket/DataCenter/DataCenterConstants.cs index 526db40c0..876bd765a 100644 --- a/src/shared/Atlassian.Bitbucket/DataCenter/DataCenterConstants.cs +++ b/src/shared/Atlassian.Bitbucket/DataCenter/DataCenterConstants.cs @@ -30,6 +30,7 @@ public static class EnvironmentVariables public const string OAuthClientId = "GCM_BITBUCKET_DATACENTER_CLIENTID"; public const string OAuthClientSecret = "GCM_BITBUCKET_DATACENTER_CLIENTSECRET"; public const string OAuthRedirectUri = "GCM_BITBUCKET_DATACENTER_OAUTH_REDIRECTURI"; + public const string HttpPath = "GCM_BITBUCKET_DATACENTER_HTTP_PATH"; } public static class GitConfiguration @@ -39,6 +40,7 @@ public static class Credential public const string OAuthClientId = "bitbucketDataCenterOAuthClientId"; public const string OAuthClientSecret = "bitbucketDataCenterOAuthClientSecret"; public const string OAuthRedirectUri = "bitbucketDataCenterOauthRedirectUri"; + public const string HttpPath = "bitbucketDataCenterHttpPath"; } } }