Support refreshtokens in OAuth flow (#2749)

* Support refreshtokens in OAuth flow
Fixes #2731

* Added summary to OauthToken.cs constructors

* Mark deprecation of non-refreshToken constructor for OauthToken

* Remove unnecessary comment

---------

Co-authored-by: Keegan Campbell <me@kfcampbell.com>
This commit is contained in:
Ken Christensen
2023-07-28 00:46:03 +02:00
committed by GitHub
parent 8974796e0b
commit bbcd33d96e
7 changed files with 233 additions and 67 deletions
@@ -0,0 +1,67 @@
using System.Diagnostics;
using System.Globalization;
using Octokit.Internal;
namespace Octokit
{
/// <summary>
/// Used to create an Oauth login request.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class OauthTokenRenewalRequest : RequestParameters
{
/// <summary>
/// Creates an instance of the OAuth token refresh request.
/// </summary>
/// <param name="clientId">The client Id you received from GitHub when you registered the application.</param>
/// <param name="clientSecret">The client secret you received from GitHub when you registered.</param>
/// <param name="refreshToken">The refresh token you received when making the original oauth token request.</param>
public OauthTokenRenewalRequest(string clientId, string clientSecret, string refreshToken)
{
Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId));
Ensure.ArgumentNotNullOrEmptyString(clientSecret, nameof(clientSecret));
Ensure.ArgumentNotNullOrEmptyString(refreshToken, nameof(refreshToken));
ClientId = clientId;
ClientSecret = clientSecret;
RefreshToken = refreshToken;
}
/// <summary>
/// The client Id you received from GitHub when you registered the application.
/// </summary>
[Parameter(Key = "client_id")]
public string ClientId { get; private set; }
/// <summary>
/// The client secret you received from GitHub when you registered.
/// </summary>
[Parameter(Key = "client_secret")]
public string ClientSecret { get; private set; }
/// <summary>
/// The type of grant. Should be ommited, unless renewing an access token.
/// </summary>
[Parameter(Key = "grant_type")]
public string GrantType { get; private set; } = "refresh_token";
/// <summary>
/// The refresh token you received as a response to making the <see cref="IOauthClient.CreateAccessToken">OAuth login
/// request</see>.
/// </summary>
[Parameter(Key = "refresh_token")]
public string RefreshToken { get; private set; }
internal string DebuggerDisplay
{
get
{
return string.Format(CultureInfo.InvariantCulture, "ClientId: {0}, ClientSecret: {1}, GrantType: {2}, RefreshToken: {3}",
ClientId,
ClientSecret,
GrantType,
RefreshToken);
}
}
}
}
+58 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using Octokit.Internal;
@@ -10,6 +11,17 @@ namespace Octokit
{
public OauthToken() { }
/// <summary>
/// Initializes a new instance of the <see cref="OauthToken"/> class.
/// Use this constructor when you don't have a refreshToken.
/// </summary>
/// <param name="tokenType">The type of token returned by GitHub.</param>
/// <param name="accessToken">The access token returned by GitHub.</param>
/// <param name="scope">The auhtorization scope of the returned token.</param>
/// <param name="error">The error code returned by the GitHub API.</param>
/// <param name="errorDescription">The error message, if any, returned by the GitHub API.</param>
/// <param name="errorUri">The GitHub documentation link, detailing the error message.</param>
[Obsolete("This constructor is being deprecated and will be removed in the future. Use OauthToken.OauthToken (with refreshToken paramters) instead.")]
public OauthToken(string tokenType, string accessToken, IReadOnlyList<string> scope, string error, string errorDescription, string errorUri)
{
this.TokenType = tokenType;
@@ -20,6 +32,32 @@ namespace Octokit
this.ErrorUri = errorUri;
}
/// <summary>
/// Initializes a new instance of the <see cref="OauthToken"/> class.
/// Use this constructor by default.
/// </summary>
/// <param name="tokenType">The type of token returned by GitHub.</param>
/// <param name="accessToken">The access token returned by GitHub.</param>
/// <param name="expiresIn">The amount of seconds, before the access token expires.</param>
/// <param name="refreshToken">The refresh token returned by GitHub. Use this, to get a new access token if it expires.</param>
/// <param name="refreshTokenExpiresIn">The amount of seconds, before the refresh token expires.</param>
/// <param name="scope">The auhtorization scope of the returned token.</param>
/// <param name="error">The error code returned by the GitHub API.</param>
/// <param name="errorDescription">The error message, if any, returned by the GitHub API.</param>
/// <param name="errorUri">The GitHub documentation link, detailing the error message.</param>
public OauthToken(string tokenType, string accessToken, int expiresIn, string refreshToken, int refreshTokenExpiresIn, IReadOnlyList<string> scope, string error, string errorDescription, string errorUri)
{
this.TokenType = tokenType;
this.AccessToken = accessToken;
this.ExpiresIn = expiresIn;
this.RefreshToken = refreshToken;
this.RefreshTokenExpiresIn = refreshTokenExpiresIn;
this.Scope = scope;
this.Error = error;
this.ErrorDescription = errorDescription;
this.ErrorUri = errorUri;
}
/// <summary>
/// The type of OAuth token
/// </summary>
@@ -30,6 +68,25 @@ namespace Octokit
/// </summary>
public string AccessToken { get; private set; }
/// <summary>
/// The amount of seconds, until the acces token expires.
/// </summary>
[Parameter(Key = "expires_in")]
public int ExpiresIn { get; private set; }
/// <summary>
/// The secret refresh token.
/// Use this to get a new access token, without going through the OAuth flow again.
/// </summary>
[Parameter(Key = "refresh_token")]
public string RefreshToken { get; private set; }
/// <summary>
/// The amount of seconds, until the refresh token expires.
/// </summary>
[Parameter(Key = "refresh_token_expires_in")]
public int RefreshTokenExpiresIn { get; private set; }
/// <summary>
/// The list of scopes the token includes.
/// </summary>