Skip to content

Commit 61d0405

Browse files
committed
gitlab: use auth mode constant and detect oauth cfg
Use the constant to define the AuthenticationModes available for gitlab.com. Also dynamically allow browser as a supported auth mode for non-dotcom instances that have an OAuth client ID configured.
1 parent cdce323 commit 61d0405

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

src/shared/GitLab.Tests/GitLabHostProviderTests.cs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Threading.Tasks;
43
using GitCredentialManager;
5-
using GitCredentialManager.Authentication.OAuth;
64
using GitCredentialManager.Tests.Objects;
7-
using Moq;
85
using Xunit;
96

107
namespace GitLab.Tests
@@ -28,5 +25,49 @@ public void GitLabHostProvider_IsSupported(string protocol, string host, bool ex
2825
var provider = new GitLabHostProvider(new TestCommandContext());
2926
Assert.Equal(expected, provider.IsSupported(input));
3027
}
28+
29+
[Fact]
30+
public void GitLabHostProvider_GetSupportedAuthenticationModes_DotCom_ReturnsDotComModes()
31+
{
32+
Uri targetUri = GitLabConstants.GitLabDotCom;
33+
AuthenticationModes expected = GitLabConstants.DotComAuthenticationModes;
34+
35+
var context = new TestCommandContext();
36+
var provider = new GitLabHostProvider(context);
37+
AuthenticationModes actual = provider.GetSupportedAuthenticationModes(targetUri);
38+
39+
Assert.Equal(expected, actual);
40+
}
41+
42+
[Fact]
43+
public void GitLabHostProvider_GetSupportedAuthenticationModes_Custom_NoOAuthConfig_ReturnsBasicPat()
44+
{
45+
var targetUri = new Uri("https://gitlab.example.com");
46+
var expected = AuthenticationModes.Basic
47+
| AuthenticationModes.Pat;
48+
49+
var context = new TestCommandContext();
50+
var provider = new GitLabHostProvider(context);
51+
AuthenticationModes actual = provider.GetSupportedAuthenticationModes(targetUri);
52+
53+
Assert.Equal(expected, actual);
54+
}
55+
56+
[Fact]
57+
public void GitLabHostProvider_GetSupportedAuthenticationModes_Custom_WithOAuthConfig_ReturnsBasicPatBrowser()
58+
{
59+
var targetUri = new Uri("https://gitlab.example.com");
60+
var expected = AuthenticationModes.Basic
61+
| AuthenticationModes.Pat
62+
| AuthenticationModes.Browser;
63+
64+
var context = new TestCommandContext();
65+
context.Environment.Variables[GitLabConstants.EnvironmentVariables.DevOAuthClientId] = "abcdefg1234567";
66+
67+
var provider = new GitLabHostProvider(context);
68+
AuthenticationModes actual = provider.GetSupportedAuthenticationModes(targetUri);
69+
70+
Assert.Equal(expected, actual);
71+
}
3172
}
3273
}

src/shared/GitLab/GitLabConstants.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace GitLab
44
{
55
public static class GitLabConstants
66
{
7+
public static readonly Uri GitLabDotCom = new Uri("https://gitlab.com");
8+
79
// owned by https://gitlab.com/gitcredentialmanager
810
public const string OAuthClientId = "172b9f227872b5dde33f4d9b1db06a6a5515ae79508e7a00c973c85ce490671e";
911
public const string OAuthClientSecret = "7da92770d1447508601e4ba026bc5eb655c8268e818cd609889cc9bae2023f39";
@@ -13,7 +15,7 @@ public static class GitLabConstants
1315
public static readonly Uri OAuthAuthorizationEndpointRelativeUri = new Uri("/oauth/authorize", UriKind.Relative);
1416
public static readonly Uri OAuthTokenEndpointRelativeUri = new Uri("/oauth/token", UriKind.Relative);
1517

16-
public const AuthenticationModes DotComAuthenticationModes = AuthenticationModes.Browser | AuthenticationModes.Pat;
18+
public const AuthenticationModes DotComAuthenticationModes = AuthenticationModes.All;
1719

1820
public static class EnvironmentVariables
1921
{
@@ -35,6 +37,13 @@ public static class Credential
3537
}
3638
}
3739

38-
public static bool IsGitLabDotCom(Uri uri) => StringComparer.OrdinalIgnoreCase.Equals(uri.Host, "gitlab.com");
40+
public static class HelpUrls
41+
{
42+
public const string GitLab = "https://aka.ms/gcm/gitlab";
43+
}
44+
45+
public static bool IsGitLabDotCom(Uri uri) => StringComparer.OrdinalIgnoreCase.Equals(uri.Host, GitLabDotCom.Host);
46+
47+
public static bool IsGitLabDotComClientId(string clientId) => StringComparer.OrdinalIgnoreCase.Equals(clientId, OAuthClientId);
3948
}
4049
}

src/shared/GitLab/GitLabHostProvider.cs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,39 @@ internal AuthenticationModes GetSupportedAuthenticationModes(Uri targetUri)
132132
}
133133
}
134134

135+
// GitLab.com has well-known supported auth modes
135136
if (GitLabConstants.IsGitLabDotCom(targetUri))
136137
{
137-
return AuthenticationModes.All;
138+
return GitLabConstants.DotComAuthenticationModes;
138139
}
139140

140-
Context.Streams.Error.WriteLine($"Missing OAuth configuration for {targetUri.Host}, see https://github.com/GitCredentialManager/git-credential-manager/blob/main/docs/gitlab.md.");
141-
// Would like to query password_authentication_enabled_for_git, but can't unless logged in https://gitlab.com/gitlab-org/gitlab/-/issues/349463
142-
return AuthenticationModes.Basic | AuthenticationModes.Pat;
141+
// Try to detect what auth modes are available for this non-GitLab.com host.
142+
// Assume that PATs are always available to give at least one option to users!
143+
var modes = AuthenticationModes.Pat;
144+
145+
// If there is a configured OAuth client ID (that isn't GitLab.com's client ID)
146+
// then assume OAuth is possible.
147+
string oauthClientId = GitLabOAuth2Client.GetClientId(Context.Settings);
148+
if (!GitLabConstants.IsGitLabDotComClientId(oauthClientId))
149+
{
150+
modes |= AuthenticationModes.Browser;
151+
}
152+
else
153+
{
154+
// Tell the user that they may wish to configure OAuth for this GitLab instance
155+
Context.Streams.Error.WriteLine(
156+
$"warning: missing OAuth configuration for {targetUri.Host} - see {GitLabConstants.HelpUrls.GitLab} for more information");
157+
}
158+
159+
// Would like to query password_authentication_enabled_for_git, but can't unless logged in https://gitlab.com/gitlab-org/gitlab/-/issues/349463.
160+
// For now assume password auth is always available.
161+
bool supportsBasic = true;
162+
if (supportsBasic)
163+
{
164+
modes |= AuthenticationModes.Basic;
165+
}
166+
167+
return modes;
143168
}
144169

145170
// <remarks>Stores OAuth tokens as a side effect</remarks>

0 commit comments

Comments
 (0)