-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathAuthenticationConfigurationViewModel.cs
116 lines (96 loc) · 3.82 KB
/
AuthenticationConfigurationViewModel.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2021 Valters Melnalksnis
// Licensed under the GNU Affero General Public License v3.0 or later.
// See LICENSE.txt file in the project root for full license information.
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PropertyChanged.SourceGenerator;
namespace Gnomeshade.Avalonia.Core.Configuration;
/// <summary>View model for configuring options for authentication.</summary>
public sealed partial class AuthenticationConfigurationViewModel : ConfigurationViewModel
{
private readonly ILogger<AuthenticationConfigurationViewModel> _logger;
private readonly HttpClient _httpClient;
private CancellationTokenSource? _cancellationTokenSource;
/// <inheritdoc cref="OidcOptions.Authority"/>
[Notify]
[AlsoNotify(nameof(IsValid))]
[PropertyAttribute("[System.ComponentModel.DataAnnotations.Required]")]
private string? _authority;
/// <inheritdoc cref="OidcOptions.ClientId"/>
[Notify]
[AlsoNotify(nameof(IsValid))]
[PropertyAttribute("[System.ComponentModel.DataAnnotations.Required]")]
private string? _clientId;
/// <inheritdoc cref="OidcOptions.ClientSecret"/>
[Notify]
[AlsoNotify(nameof(IsValid))]
private string? _clientSecret;
/// <summary>Initializes a new instance of the <see cref="AuthenticationConfigurationViewModel"/> class.</summary>
/// <param name="activityService">Service for indicating the activity of the application to the user.</param>
/// <param name="optionsMonitor">Options monitor of user preferences.</param>
/// <param name="configurationWriter">Used to persist user configuration.</param>
/// <param name="logger">Logger for logging in the specified category.</param>
/// <param name="httpClient">HTTP client URI validation.</param>
public AuthenticationConfigurationViewModel(
IActivityService activityService,
IOptionsMonitor<UserConfiguration> optionsMonitor,
UserConfigurationWriter configurationWriter,
ILogger<AuthenticationConfigurationViewModel> logger,
HttpClient httpClient)
: base(activityService, optionsMonitor, configurationWriter)
{
_logger = logger;
_httpClient = httpClient;
_authority = optionsMonitor.CurrentValue.Oidc?.Authority?.ToString();
_clientId = optionsMonitor.CurrentValue.Oidc?.ClientId;
_clientSecret = optionsMonitor.CurrentValue.Oidc?.ClientSecret;
}
/// <inheritdoc />
public override Task<bool> IsValid => IsValidAsync();
/// <inheritdoc />
internal override void UpdateConfiguration(UserConfiguration configuration)
{
if (Authority is null || ClientId is null)
{
throw new InvalidOperationException();
}
configuration.Oidc ??= new();
configuration.Oidc.Authority = new(Authority);
configuration.Oidc.ClientId = ClientId;
configuration.Oidc.ClientSecret = ClientSecret;
}
private async Task<bool> IsValidAsync()
{
ErrorMessage = null;
_cancellationTokenSource?.Cancel();
if (Authority is null || ClientId is null)
{
return false;
}
_cancellationTokenSource = new();
var cancellationToken = _cancellationTokenSource.Token;
try
{
await Task.Delay(UserInputDelay, cancellationToken);
using var activity = ActivityService.BeginActivity("Checking connectivity to authentication provider");
using var response = await _httpClient.GetAsync(new Uri(Authority), cancellationToken);
if (response.StatusCode is HttpStatusCode.OK)
{
return true;
}
ErrorMessage = $"Received status code {response.StatusCode:G} from authentication provider";
return false;
}
catch (Exception exception) when (exception is not TaskCanceledException)
{
_logger.LogWarning(exception, "Failed to check authentication provider status");
ErrorMessage = $"Failed to check the status of the authentication provider.{Environment.NewLine}{exception.Message}";
return false;
}
}
}