Fixed secret retrieval for connection testing while adding an ERI data source (#325)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2025-03-11 13:57:47 +01:00
1 parent 0125f48f61
commit 2429788ccc
10 files changed
+53 -40

No files matched your search

@@ -1,10 +1,14 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using AIStudio.Settings;
namespace AIStudio.Tools.ERIClient;
public abstract class ERIClientBase(string baseAddress) : IDisposable
public abstract class ERIClientBase(IERIDataSource dataSource) : IDisposable
{
protected readonly IERIDataSource dataSource = dataSource;
protected static readonly JsonSerializerOptions JSON_OPTIONS = new()
{
WriteIndented = true,
@@ -21,7 +25,7 @@ public abstract class ERIClientBase(string baseAddress) : IDisposable
protected readonly HttpClient httpClient = new()
{
BaseAddress = new Uri(baseAddress),
BaseAddress = new Uri($"{dataSource.Hostname}:{dataSource.Port}"),
};
protected string securityToken = string.Empty;
@@ -7,7 +7,7 @@ public static class ERIClientFactory
{
public static IERIClient? Get(ERIVersion version, IERIDataSource dataSource) => version switch
{
ERIVersion.V1 => new ERIClientV1($"{dataSource.Hostname}:{dataSource.Port}"),
ERIVersion.V1 => new ERIClientV1(dataSource),
_ => null
};
@@ -7,7 +7,7 @@ using AIStudio.Tools.Services;
namespace AIStudio.Tools.ERIClient;
public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIClient
public class ERIClientV1(IERIDataSource dataSource) : ERIClientBase(dataSource), IERIClient
{
#region Implementation of IERIClient
@@ -59,13 +59,13 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
}
}
public async Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default)
public async Task<APIResponse<AuthResponse>> AuthenticateAsync(RustService rustService, string? temporarySecret = null, CancellationToken cancellationToken = default)
{
try
{
var authMethod = dataSource.AuthMethod;
var username = dataSource.Username;
switch (dataSource.AuthMethod)
var authMethod = this.dataSource.AuthMethod;
var username = this.dataSource.Username;
switch (this.dataSource.AuthMethod)
{
case AuthMethod.NONE:
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
@@ -99,17 +99,24 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
}
case AuthMethod.USERNAME_PASSWORD:
var passwordResponse = await rustService.GetSecret(dataSource);
if (!passwordResponse.Success)
string password;
if (string.IsNullOrWhiteSpace(temporarySecret))
{
return new()
var passwordResponse = await rustService.GetSecret(this.dataSource);
if (!passwordResponse.Success)
{
Successful = false,
Message = "Failed to retrieve the password."
};
}
return new()
{
Successful = false,
Message = "Failed to retrieve the password."
};
}
password = await passwordResponse.Secret.Decrypt(Program.ENCRYPTION);
}
else
password = temporarySecret;
var password = await passwordResponse.Secret.Decrypt(Program.ENCRYPTION);
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
{
// We must send both values inside the header. The username field is named 'user'.
@@ -146,17 +153,24 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
}
case AuthMethod.TOKEN:
var tokenResponse = await rustService.GetSecret(dataSource);
if (!tokenResponse.Success)
string token;
if (string.IsNullOrWhiteSpace(temporarySecret))
{
return new()
var tokenResponse = await rustService.GetSecret(this.dataSource);
if (!tokenResponse.Success)
{
Successful = false,
Message = "Failed to retrieve the access token."
};
}
return new()
{
Successful = false,
Message = "Failed to retrieve the access token."
};
}
token = await tokenResponse.Secret.Decrypt(Program.ENCRYPTION);
}
else
token = temporarySecret;
var token = await tokenResponse.Secret.Decrypt(Program.ENCRYPTION);
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
{
request.Headers.Add("Authorization", $"Bearer {token}");
@@ -1,4 +1,3 @@
using AIStudio.Settings;
using AIStudio.Tools.ERIClient.DataModel;
using AIStudio.Tools.Services;
@@ -19,11 +18,11 @@ public interface IERIClient : IDisposable
/// <summary>
/// Authenticate the user to the ERI server.
/// </summary>
/// <param name="dataSource">The data source to use.</param>
/// <param name="rustService">The Rust service.</param>
/// <param name="temporarySecret">The temporary secret when adding a new data source, and the secret is not yet stored in the OS.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The authentication response.</returns>
public Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default);
public Task<APIResponse<AuthResponse>> AuthenticateAsync(RustService rustService, string? temporarySecret = null, CancellationToken cancellationToken = default);
/// <summary>
/// Retrieves the data source information from the ERI server.
@@ -113,7 +113,7 @@ public sealed class DataSourceService
}
this.logger.LogInformation($"Authenticating with ERI source '{source.Name}' (id={source.Id})...");
var loginResult = await client.AuthenticateAsync(eriSource, this.rustService, cancellationTokenSource.Token);
var loginResult = await client.AuthenticateAsync(this.rustService, cancellationToken: cancellationTokenSource.Token);
if (!loginResult.Successful)
{
this.logger.LogWarning($"Authentication with ERI source '{source.Name}' (id={source.Id}) failed. We skip this source. Reason: {loginResult.Message}");