-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert nexus mods oauth login into a job
- Loading branch information
Showing
14 changed files
with
206 additions
and
165 deletions.
There are no files selected for viewing
18 changes: 9 additions & 9 deletions
18
src/Abstractions/NexusMods.Abstractions.Jobs/IJobDefinition.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 0 additions & 12 deletions
12
src/Abstractions/NexusMods.Abstractions.NexusWebApi/Constants.cs
This file was deleted.
Oops, something went wrong.
11 changes: 11 additions & 0 deletions
11
src/Abstractions/NexusMods.Abstractions.NexusWebApi/IOAuthJob.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using NexusMods.Abstractions.Jobs; | ||
|
||
namespace NexusMods.Abstractions.NexusWebApi; | ||
|
||
/// <summary> | ||
/// Represents a job for logging in using OAuth. | ||
/// </summary> | ||
public interface IOAuthJob : IJobDefinition, IDisposable | ||
{ | ||
R3.Subject<Uri> LoginUriSubject { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/Networking/NexusMods.Networking.NexusWebApi/OAuthJob.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using System.Reactive.Linq; | ||
using System.Reactive.Subjects; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using DynamicData.Kernel; | ||
using NexusMods.Abstractions.Jobs; | ||
using NexusMods.Abstractions.NexusWebApi; | ||
using NexusMods.Abstractions.NexusWebApi.DTOs.OAuth; | ||
using NexusMods.Abstractions.NexusWebApi.Types; | ||
using NexusMods.CrossPlatform.Process; | ||
using NexusMods.Extensions.BCL; | ||
using NexusMods.Networking.NexusWebApi.Auth; | ||
|
||
namespace NexusMods.Networking.NexusWebApi; | ||
|
||
internal sealed class OAuthJob : IOAuthJob, IJobDefinitionWithStart<OAuthJob, Optional<JwtTokenReply>> | ||
{ | ||
private readonly IIDGenerator _idGenerator; | ||
private readonly IOSInterop _os; | ||
private readonly HttpClient _httpClient; | ||
private readonly Subject<NXMOAuthUrl> _nxmUrlMessages; | ||
|
||
public R3.Subject<Uri> LoginUriSubject { get; } = new(); | ||
|
||
private OAuthJob( | ||
IIDGenerator idGenerator, | ||
IOSInterop os, | ||
HttpClient httpClient, | ||
Subject<NXMOAuthUrl> nxmUrlMessages) | ||
{ | ||
_idGenerator = idGenerator; | ||
_os = os; | ||
_httpClient = httpClient; | ||
_nxmUrlMessages = nxmUrlMessages; | ||
} | ||
|
||
public static IJobTask<OAuthJob, Optional<JwtTokenReply>> Create( | ||
IJobMonitor jobMonitor, | ||
IIDGenerator idGenerator, | ||
IOSInterop os, | ||
HttpClient httpClient, | ||
Subject<NXMOAuthUrl> nxmUrlMessages) | ||
{ | ||
var job = new OAuthJob(idGenerator, os, httpClient, nxmUrlMessages); | ||
return jobMonitor.Begin<OAuthJob, Optional<JwtTokenReply>>(job); | ||
} | ||
|
||
public async ValueTask<Optional<JwtTokenReply>> StartAsync(IJobContext<OAuthJob> context) | ||
{ | ||
// see https://www.rfc-editor.org/rfc/rfc7636#section-4.1 | ||
var codeVerifier = _idGenerator.UUIDv4().ToBase64(); | ||
|
||
// see https://www.rfc-editor.org/rfc/rfc7636#section-4.2 | ||
var codeChallengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier)); | ||
var codeChallenge = StringBase64Extensions.Base64UrlEncode(codeChallengeBytes); | ||
|
||
var state = _idGenerator.UUIDv4(); | ||
var uri = OAuth.GenerateAuthorizeUrl(codeChallenge, state); | ||
LoginUriSubject.OnNext(uri); | ||
|
||
var cts = CancellationTokenSource.CreateLinkedTokenSource(context.CancellationToken); | ||
|
||
// Start listening first, otherwise we might miss the message | ||
var codeTask = _nxmUrlMessages | ||
.Where(oauth => oauth.State == state) | ||
.Select(url => url.OAuth.Code) | ||
.Where(code => code is not null) | ||
.Select(code => code!) | ||
.ToAsyncEnumerable() | ||
.FirstAsync(cts.Token); | ||
|
||
// see https://www.rfc-editor.org/rfc/rfc7636#section-4.3 | ||
await _os.OpenUrl(uri, cancellationToken: context.CancellationToken); | ||
|
||
cts.CancelAfter(TimeSpan.FromMinutes(3)); | ||
var code = await codeTask; | ||
|
||
var token = await OAuth.AuthorizeToken(codeVerifier, code, _httpClient, context.CancellationToken); | ||
return token; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
LoginUriSubject.Dispose(); | ||
} | ||
} |
8 changes: 3 additions & 5 deletions
8
src/NexusMods.App.UI/Overlays/Login/INexusLoginOverlayViewModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
using System.Windows.Input; | ||
|
||
namespace NexusMods.App.UI.Overlays.Login; | ||
namespace NexusMods.App.UI.Overlays.Login; | ||
|
||
public interface INexusLoginOverlayViewModel : IOverlayViewModel | ||
{ | ||
public ICommand Cancel { get; } | ||
public Uri Uri { get; } | ||
public R3.ReactiveCommand Cancel { get; } | ||
public Uri? Uri { get; } | ||
} |
6 changes: 2 additions & 4 deletions
6
src/NexusMods.App.UI/Overlays/Login/NexusLoginOverlayDesignerViewModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
using System.Windows.Input; | ||
|
||
namespace NexusMods.App.UI.Overlays.Login; | ||
namespace NexusMods.App.UI.Overlays.Login; | ||
|
||
public class NexusLoginOverlayDesignerViewModel : AOverlayViewModel<INexusLoginOverlayViewModel>, INexusLoginOverlayViewModel | ||
{ | ||
public ICommand Cancel { get; } = Initializers.ICommand; | ||
public R3.ReactiveCommand Cancel { get; } = new(); | ||
public Uri Uri { get; } = new("https://www.nexusmods.com/some/login?name=John&key=1234567890"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.