mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 14:37:44 +01:00
Migrate GitHubOAuthValidator to IGitHubService
This commit is contained in:
@@ -21,9 +21,9 @@ namespace Tgstation.Server.Host.Security.OAuth
|
||||
public OAuthProvider Provider => OAuthProvider.GitHub;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IGitHubClientFactory"/> for the <see cref="GitHubOAuthValidator"/>.
|
||||
/// The <see cref="IGitHubServiceFactory"/> for the <see cref="GitHubOAuthValidator"/>.
|
||||
/// </summary>
|
||||
readonly IGitHubClientFactory gitHubClientFactory;
|
||||
readonly IGitHubServiceFactory gitHubServiceFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="GitHubOAuthValidator"/>.
|
||||
@@ -38,15 +38,15 @@ namespace Tgstation.Server.Host.Security.OAuth
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GitHubOAuthValidator"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gitHubClientFactory">The value of <see cref="gitHubClientFactory"/>.</param>
|
||||
/// <param name="gitHubServiceFactory">The value of <see cref="gitHubServiceFactory"/>.</param>
|
||||
/// <param name="logger">The value of <see cref="logger"/>.</param>
|
||||
/// <param name="oAuthConfiguration">The value of <see cref="oAuthConfiguration"/>.</param>
|
||||
public GitHubOAuthValidator(
|
||||
IGitHubClientFactory gitHubClientFactory,
|
||||
IGitHubServiceFactory gitHubServiceFactory,
|
||||
ILogger<GitHubOAuthValidator> logger,
|
||||
OAuthConfiguration oAuthConfiguration)
|
||||
{
|
||||
this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
|
||||
this.gitHubServiceFactory = gitHubServiceFactory ?? throw new ArgumentNullException(nameof(gitHubServiceFactory));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
this.oAuthConfiguration = oAuthConfiguration ?? throw new ArgumentNullException(nameof(oAuthConfiguration));
|
||||
}
|
||||
@@ -57,35 +57,21 @@ namespace Tgstation.Server.Host.Security.OAuth
|
||||
if (code == null)
|
||||
throw new ArgumentNullException(nameof(code));
|
||||
|
||||
var client = gitHubClientFactory.CreateClient();
|
||||
try
|
||||
{
|
||||
logger.LogTrace("Validating response code...");
|
||||
var response = await client
|
||||
.Oauth
|
||||
.CreateAccessToken(
|
||||
new OauthTokenRequest(
|
||||
oAuthConfiguration.ClientId,
|
||||
oAuthConfiguration.ClientSecret,
|
||||
code)
|
||||
{
|
||||
RedirectUri = oAuthConfiguration.RedirectUrl,
|
||||
})
|
||||
;
|
||||
|
||||
var token = response.AccessToken;
|
||||
var gitHubService = gitHubServiceFactory.CreateService();
|
||||
var token = await gitHubService.CreateOAuthAccessToken(oAuthConfiguration, code, cancellationToken);
|
||||
if (token == null)
|
||||
return null;
|
||||
|
||||
var authenticatedClient = gitHubClientFactory.CreateClient(token);
|
||||
var authenticatedClient = gitHubServiceFactory.CreateService(token);
|
||||
|
||||
logger.LogTrace("Getting user details...");
|
||||
var userDetails = await authenticatedClient
|
||||
.User
|
||||
.Current()
|
||||
;
|
||||
var userId = await authenticatedClient.GetCurrentUserId(cancellationToken);
|
||||
|
||||
return userDetails.Id.ToString(CultureInfo.InvariantCulture);
|
||||
return userId.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (RateLimitExceededException)
|
||||
{
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace Tgstation.Server.Host.Security.OAuth
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OAuthProviders"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gitHubClientFactory">The <see cref="IGitHubClientFactory"/> to use.</param>
|
||||
/// <param name="gitHubServiceFactory">The <see cref="IGitHubServiceFactory"/> to use.</param>
|
||||
/// <param name="httpClientFactory">The <see cref="IAbstractHttpClientFactory"/> to use.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> to use.</param>
|
||||
/// <param name="securityConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the <see cref="SecurityConfiguration"/> to use.</param>
|
||||
public OAuthProviders(
|
||||
IGitHubClientFactory gitHubClientFactory,
|
||||
IGitHubServiceFactory gitHubServiceFactory,
|
||||
IAbstractHttpClientFactory httpClientFactory,
|
||||
ILoggerFactory loggerFactory,
|
||||
IOptions<SecurityConfiguration> securityConfigurationOptions)
|
||||
@@ -49,7 +49,7 @@ namespace Tgstation.Server.Host.Security.OAuth
|
||||
if (securityConfiguration.OAuth.TryGetValue(OAuthProvider.GitHub, out var gitHubConfig))
|
||||
validatorsBuilder.Add(
|
||||
new GitHubOAuthValidator(
|
||||
gitHubClientFactory,
|
||||
gitHubServiceFactory,
|
||||
loggerFactory.CreateLogger<GitHubOAuthValidator>(),
|
||||
gitHubConfig));
|
||||
|
||||
|
||||
@@ -44,6 +44,33 @@ namespace Tgstation.Server.Host.Utils.GitHub
|
||||
this.updatesConfiguration = updatesConfiguration ?? throw new ArgumentNullException(nameof(updatesConfiguration));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken)
|
||||
{
|
||||
if (oAuthConfiguration == null)
|
||||
throw new ArgumentNullException(nameof(oAuthConfiguration));
|
||||
|
||||
if (code == null)
|
||||
throw new ArgumentNullException(nameof(code));
|
||||
|
||||
logger.LogTrace("CreateOAuthAccessToken");
|
||||
|
||||
var response = await gitHubClient
|
||||
.Oauth
|
||||
.CreateAccessToken(
|
||||
new OauthTokenRequest(
|
||||
oAuthConfiguration.ClientId,
|
||||
oAuthConfiguration.ClientSecret,
|
||||
code)
|
||||
{
|
||||
RedirectUri = oAuthConfiguration.RedirectUrl,
|
||||
})
|
||||
.WithToken(cancellationToken);
|
||||
|
||||
var token = response.AccessToken;
|
||||
return token;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<Dictionary<Version, Release>> GetTgsReleases(CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -90,5 +117,14 @@ namespace Tgstation.Server.Host.Utils.GitHub
|
||||
|
||||
return repoUrl;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> GetCurrentUserId(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("CreateOAuthAccessToken");
|
||||
|
||||
var userDetails = await gitHubClient.User.Current().WithToken(cancellationToken);
|
||||
return userDetails.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
|
||||
|
||||
using Octokit;
|
||||
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
|
||||
namespace Tgstation.Server.Host.Utils.GitHub
|
||||
{
|
||||
/// <summary>
|
||||
@@ -26,5 +28,21 @@ namespace Tgstation.Server.Host.Utils.GitHub
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of TGS <see cref="Release"/>s keyed by their <see cref="Version"/>.</returns>
|
||||
/// <remarks>GitHub has been known to return incomplete results from the API with this call.</remarks>
|
||||
Task<Dictionary<Version, Release>> GetTgsReleases(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to get an OAuth token from a given <paramref name="code"/>.
|
||||
/// </summary>
|
||||
/// <param name="oAuthConfiguration">The <see cref="OAuthConfiguration"/>. Must have <see cref="OAuthConfiguration.RedirectUrl"/>, <see cref="OAuthConfigurationBase.ClientId"/> and <see cref="OAuthConfigurationBase.ClientSecret"/> set.</param>
|
||||
/// <param name="code">The OAuth response code.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="string"/> representing the returned OAuth code from GitHub on success, <see langword="null"/> otherwise.</returns>
|
||||
Task<string> CreateOAuthAccessToken(OAuthConfiguration oAuthConfiguration, string code, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Get the current user's ID.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the current user's ID.</returns>
|
||||
Task<int> GetCurrentUserId(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user