|
|
|
@ -1,5 +1,6 @@ |
|
|
|
using Microsoft.Extensions.Hosting; |
|
|
|
using OpenIddict.Client; |
|
|
|
using Spectre.Console; |
|
|
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
|
|
|
using static OpenIddict.Abstractions.OpenIddictExceptions; |
|
|
|
using static OpenIddict.Client.WebIntegration.OpenIddictClientWebIntegrationConstants; |
|
|
|
@ -10,8 +11,6 @@ using IHostApplicationLifetime = Microsoft.Extensions.Hosting.IApplicationLifeti |
|
|
|
|
|
|
|
namespace OpenIddict.Sandbox.Console.Client; |
|
|
|
|
|
|
|
using Console = System.Console; |
|
|
|
|
|
|
|
public class InteractiveService : BackgroundService |
|
|
|
{ |
|
|
|
private readonly IHostApplicationLifetime _lifetime; |
|
|
|
@ -36,23 +35,9 @@ public class InteractiveService : BackgroundService |
|
|
|
|
|
|
|
while (!stoppingToken.IsCancellationRequested) |
|
|
|
{ |
|
|
|
string? provider; |
|
|
|
|
|
|
|
do |
|
|
|
{ |
|
|
|
Console.WriteLine("Type '1' + ENTER to log in using the local server or '2' + ENTER to log in using GitHub."); |
|
|
|
|
|
|
|
provider = await ReadLineAsync(stoppingToken) switch |
|
|
|
{ |
|
|
|
"1" => "Local", |
|
|
|
"2" => Providers.GitHub, |
|
|
|
_ => null |
|
|
|
}; |
|
|
|
} |
|
|
|
var provider = await GetSelectedProviderAsync(stoppingToken); |
|
|
|
|
|
|
|
while (string.IsNullOrEmpty(provider)); |
|
|
|
|
|
|
|
Console.WriteLine("Launching the system browser."); |
|
|
|
AnsiConsole.MarkupLine("[cyan]Launching the system browser.[/]"); |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
@ -61,31 +46,35 @@ public class InteractiveService : BackgroundService |
|
|
|
var (_, _, principal) = await _service.AuthenticateInteractivelyAsync( |
|
|
|
provider, cancellationToken: stoppingToken); |
|
|
|
|
|
|
|
Console.WriteLine($"Welcome, {principal.FindFirst(Claims.Name)!.Value}."); |
|
|
|
AnsiConsole.MarkupLineInterpolated($"[green]Welcome, {principal.FindFirst(Claims.Name)!.Value}.[/]"); |
|
|
|
} |
|
|
|
|
|
|
|
catch (OperationCanceledException) |
|
|
|
{ |
|
|
|
Console.WriteLine("The authentication process was aborted."); |
|
|
|
AnsiConsole.MarkupLine("[red]The authentication process was aborted.[/]"); |
|
|
|
} |
|
|
|
|
|
|
|
catch (ProtocolException exception) when (exception.Error is Errors.AccessDenied) |
|
|
|
{ |
|
|
|
Console.WriteLine("The authorization was denied by the end user."); |
|
|
|
AnsiConsole.MarkupLine("[yellow]The authorization was denied by the end user.[/]"); |
|
|
|
} |
|
|
|
|
|
|
|
catch |
|
|
|
{ |
|
|
|
Console.WriteLine("An error occurred while trying to authenticate the user."); |
|
|
|
AnsiConsole.MarkupLine("[red]An error occurred while trying to authenticate the user.[/]"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static async Task<string?> ReadLineAsync(CancellationToken cancellationToken) |
|
|
|
static async Task<string> GetSelectedProviderAsync(CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
static string Prompt() => AnsiConsole.Prompt(new SelectionPrompt<string>() |
|
|
|
.Title("Select the authentication provider you'd like to log in with.") |
|
|
|
.AddChoices("Local", Providers.GitHub, Providers.Twitter)); |
|
|
|
|
|
|
|
#if SUPPORTS_TASK_WAIT_ASYNC
|
|
|
|
return await Task.Run(Console.ReadLine, cancellationToken).WaitAsync(cancellationToken); |
|
|
|
return await Task.Run(Prompt, cancellationToken).WaitAsync(cancellationToken); |
|
|
|
#else
|
|
|
|
var task = Task.Run(Console.ReadLine, cancellationToken); |
|
|
|
var task = Task.Run(Prompt, cancellationToken); |
|
|
|
var source = new TaskCompletionSource<bool>(TaskCreationOptions.None); |
|
|
|
|
|
|
|
using (cancellationToken.Register(static state => ((TaskCompletionSource<bool>) state!).SetResult(true), source)) |
|
|
|
|