Skip to content

Commit

Permalink
Merge pull request #147 from mjcheetham/github-oauthdevice
Browse files Browse the repository at this point in the history
Enable OAuth device authorisation grant support for GitHub
  • Loading branch information
mjcheetham committed Jul 17, 2020
2 parents 2b944be + ecf36a3 commit 0525476
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 37 deletions.
30 changes: 6 additions & 24 deletions src/shared/GitHub/GitHubAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,6 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
{
ThrowIfUserInteractionDisabled();

// If the GitHub auth stack doesn't support flows such as RFC 8628 and we do not have
// an interactive desktop session, we cannot offer OAuth authentication.
if ((modes & AuthenticationModes.OAuth) != 0
&& !Context.SessionManager.IsDesktopSession
&& !GitHubConstants.IsOAuthDeviceAuthSupported)
{
Context.Trace.WriteLine("Ignoring OAuth authentication mode because we are not in an interactive desktop session. GitHub does not support RFC 8628.");

modes &= ~AuthenticationModes.OAuth;
}

if (modes == AuthenticationModes.None)
{
throw new ArgumentException($"Must specify at least one {nameof(AuthenticationModes)}", nameof(modes));
Expand Down Expand Up @@ -211,21 +200,14 @@ public async Task<OAuth2TokenResult> GetOAuthTokenAsync(Uri targetUri, IEnumerab
{
ThrowIfTerminalPromptsDisabled();

if (GitHubConstants.IsOAuthDeviceAuthSupported)
{
OAuth2DeviceCodeResult deviceCodeResult = await oauthClient.GetDeviceCodeAsync(scopes, CancellationToken.None);

string deviceMessage = $"To complete authentication please visit {deviceCodeResult.VerificationUri} and enter the following code:" +
Environment.NewLine +
deviceCodeResult.UserCode;
Context.Terminal.WriteLine(deviceMessage);
OAuth2DeviceCodeResult deviceCodeResult = await oauthClient.GetDeviceCodeAsync(scopes, CancellationToken.None);

return await oauthClient.GetTokenByDeviceCodeAsync(deviceCodeResult, CancellationToken.None);
}
string deviceMessage = $"To complete authentication please visit {deviceCodeResult.VerificationUri} and enter the following code:" +
Environment.NewLine +
deviceCodeResult.UserCode;
Context.Terminal.WriteLine(deviceMessage);

// We'd like to try using an OAuth2 flow that does not require a web browser on this device
// such as the device code flow (RFC 8628) but GitHub's auth stack does not support this.
throw new NotSupportedException("GitHub OAuth authentication is not supported without an interactive desktop session.");
return await oauthClient.GetTokenByDeviceCodeAsync(deviceCodeResult, CancellationToken.None);
}
}

Expand Down
8 changes: 1 addition & 7 deletions src/shared/GitHub/GitHubConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static class GitHubConstants
public static readonly Uri OAuthRedirectUri = new Uri("http://localhost/");
public static readonly Uri OAuthAuthorizationEndpointRelativeUri = new Uri("/login/oauth/authorize", UriKind.Relative);
public static readonly Uri OAuthTokenEndpointRelativeUri = new Uri("/login/oauth/access_token", UriKind.Relative);
public static readonly Uri OAuthDeviceEndpointRelativeUri = new Uri("/login/oauth/authorize/device", UriKind.Relative);
public static readonly Uri OAuthDeviceEndpointRelativeUri = new Uri("/login/device/code", UriKind.Relative);

/// <summary>
/// The GitHub required HTTP accepts header value
Expand All @@ -36,12 +36,6 @@ public static class GitHubConstants
// TODO: remove Basic once the GCM OAuth app is whitelisted and does not require installation in every organization
public const AuthenticationModes DotDomAuthenticationModes = AuthenticationModes.Basic | AuthenticationModes.OAuth;

/// <summary>
/// Check if RFC 8628 is supported by GitHub.com and GHE.
/// </summary>
// TODO: remove this once device auth is supported
public const bool IsOAuthDeviceAuthSupported = false;

public static class TokenScopes
{
public const string Gist = "gist";
Expand Down
7 changes: 1 addition & 6 deletions src/shared/GitHub/GitHubOAuth2Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ private static OAuth2ServerEndpoints CreateEndpoints(Uri baseUri)
{
Uri authEndpoint = new Uri(baseUri, GitHubConstants.OAuthAuthorizationEndpointRelativeUri);
Uri tokenEndpoint = new Uri(baseUri, GitHubConstants.OAuthTokenEndpointRelativeUri);

Uri deviceAuthEndpoint = null;
if (GitHubConstants.IsOAuthDeviceAuthSupported)
{
deviceAuthEndpoint = new Uri(baseUri, GitHubConstants.OAuthDeviceEndpointRelativeUri);
}
Uri deviceAuthEndpoint = new Uri(baseUri, GitHubConstants.OAuthDeviceEndpointRelativeUri);

return new OAuth2ServerEndpoints(authEndpoint, tokenEndpoint)
{
Expand Down

0 comments on commit 0525476

Please sign in to comment.