2026-09-09 18:43:37 +02:00
using AIStudio.Provider ;
using AIStudio.Settings ;
2025-02-15 15:41:12 +01:00
using AIStudio.Settings.DataModel ;
2025-02-09 12:36:37 +01:00
using AIStudio.Tools.ERIClient.DataModel ;
2025-05-04 14:59:30 +02:00
using AIStudio.Tools.PluginSystem ;
2025-01-13 19:51:26 +01:00
namespace AIStudio.Tools.Validation ;
public sealed class DataSourceValidation
{
2026-09-09 18:43:37 +02:00
public const int MAX_NAME_LENGTH = 40 ;
2025-05-04 14:59:30 +02:00
private static string TB ( string fallbackEN ) => I18N . I . T ( fallbackEN , typeof ( DataSourceValidation ). Namespace , nameof ( DataSourceValidation ));
2026-09-09 18:43:37 +02:00
public static bool IsNameValid ( string name ) => ! string . IsNullOrWhiteSpace ( name ) && name . Length <= MAX_NAME_LENGTH && ! name . Any ( char . IsControl );
2025-05-04 14:59:30 +02:00
2025-01-13 19:51:26 +01:00
public Func < string > GetSecretStorageIssue { get ; init ; } = () => string . Empty ;
public Func < string > GetPreviousDataSourceName { get ; init ; } = () => string . Empty ;
public Func < IEnumerable < string >> GetUsedDataSourceNames { get ; init ; } = () => [];
public Func < AuthMethod > GetAuthMethod { get ; init ; } = () => AuthMethod . NONE ;
2025-02-15 15:41:12 +01:00
public Func < SecurityRequirements ?> GetSecurityRequirements { get ; init ; } = () => null ;
2026-09-09 18:43:37 +02:00
2025-01-13 19:51:26 +01:00
public Func < bool > GetSelectedCloudEmbedding { get ; init ; } = () => false ;
2026-09-09 18:43:37 +02:00
public Func < EmbeddingProvider ?> GetSelectedEmbeddingProvider { get ; init ; } = () => null ;
public Func < ConfidenceLevel > GetConfidenceLevel { get ; init ; } = () => ConfidenceLevel . NONE ;
public Func < SettingsManager ?> GetSettingsManager { get ; init ; } = () => null ;
2025-01-13 19:51:26 +01:00
public Func < bool > GetTestedConnection { get ; init ; } = () => false ;
public Func < bool > GetTestedConnectionResult { get ; init ; } = () => false ;
public Func < IReadOnlyList < AuthMethod >> GetAvailableAuthMethods { get ; init ; } = () => [];
public string? ValidatingHostname ( string hostname )
{
if ( string . IsNullOrWhiteSpace ( hostname ))
2025-05-04 14:59:30 +02:00
return TB ( "Please enter a hostname, e.g., http://localhost" );
2025-01-13 19:51:26 +01:00
if (! hostname . StartsWith ( "http://" , StringComparison . InvariantCultureIgnoreCase ) && ! hostname . StartsWith ( "https://" , StringComparison . InvariantCultureIgnoreCase ))
2025-05-04 14:59:30 +02:00
return TB ( "The hostname must start with either http:// or https://" );
2025-01-13 19:51:26 +01:00
if (! Uri . TryCreate ( hostname , UriKind . Absolute , out _ ))
2025-05-04 14:59:30 +02:00
return TB ( "The hostname is not a valid HTTP(S) URL." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidatePort ( int port )
{
if ( port is < 1 or > 65535 )
2025-05-04 14:59:30 +02:00
return TB ( "The port must be between 1 and 65535." );
2025-01-13 19:51:26 +01:00
return null ;
}
2026-09-09 18:43:37 +02:00
2025-02-15 15:41:12 +01:00
public string? ValidateSecurityPolicy ( DataSourceSecurity securityPolicy )
{
if ( securityPolicy is DataSourceSecurity . NOT_SPECIFIED )
2025-05-04 14:59:30 +02:00
return TB ( "Please select your security policy." );
2026-09-09 18:43:37 +02:00
2025-02-15 15:41:12 +01:00
var dataSourceSecurity = this . GetSecurityRequirements ();
if ( dataSourceSecurity is null )
return null ;
2026-09-09 18:43:37 +02:00
2025-02-15 15:41:12 +01:00
if ( dataSourceSecurity . Value . AllowedProviderType is ProviderType . SELF_HOSTED && securityPolicy is not DataSourceSecurity . SELF_HOSTED )
2025-05-04 14:59:30 +02:00
return TB ( "This data source can only be used with a self-hosted LLM provider. Please change the security policy." );
2026-09-09 18:43:37 +02:00
2025-02-15 15:41:12 +01:00
return null ;
}
2025-01-13 19:51:26 +01:00
public string? ValidateUsername ( string username )
{
if ( this . GetAuthMethod () is not AuthMethod . USERNAME_PASSWORD )
return null ;
if ( string . IsNullOrWhiteSpace ( username ))
2025-05-04 14:59:30 +02:00
return TB ( "The username must not be empty." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidatingSecret ( string secret )
{
var authMethod = this . GetAuthMethod ();
if ( authMethod is AuthMethod . NONE or AuthMethod . KERBEROS )
return null ;
var secretStorageIssue = this . GetSecretStorageIssue ();
if (! string . IsNullOrWhiteSpace ( secretStorageIssue ))
return secretStorageIssue ;
if ( string . IsNullOrWhiteSpace ( secret ))
return authMethod switch
{
2025-05-04 14:59:30 +02:00
AuthMethod . TOKEN => TB ( "Please enter your secure access token." ),
AuthMethod . USERNAME_PASSWORD => TB ( "Please enter your password." ),
2025-01-13 19:51:26 +01:00
2025-05-04 14:59:30 +02:00
_ => TB ( "Please enter the secret necessary for authentication." )
2025-01-13 19:51:26 +01:00
};
return null ;
}
2025-03-08 21:04:17 +01:00
public string? ValidateRetrievalProcess ( RetrievalInfo retrievalInfo )
{
if ( retrievalInfo == default )
2025-05-04 14:59:30 +02:00
return TB ( "Please select one retrieval process." );
2025-03-08 21:04:17 +01:00
return null ;
}
2025-01-13 19:51:26 +01:00
public string? ValidatingName ( string dataSourceName )
{
2026-09-09 18:43:37 +02:00
if ( string . IsNullOrWhiteSpace ( dataSourceName ))
2025-05-04 14:59:30 +02:00
return TB ( "The name must not be empty." );
2026-09-09 18:43:37 +02:00
if ( dataSourceName . Length > MAX_NAME_LENGTH )
2025-05-04 14:59:30 +02:00
return TB ( "The name must not exceed 40 characters." );
2026-09-09 18:43:37 +02:00
if ( dataSourceName . Any ( char . IsControl ))
return TB ( "The name must not contain control characters." );
2025-01-13 19:51:26 +01:00
var lowerName = dataSourceName . ToLowerInvariant ();
if ( lowerName != this . GetPreviousDataSourceName () && this . GetUsedDataSourceNames (). Contains ( lowerName ))
2025-05-04 14:59:30 +02:00
return TB ( "The name is already used by another data source. Please choose a different name." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidatePath ( string path )
{
if ( string . IsNullOrWhiteSpace ( path ))
2025-05-04 14:59:30 +02:00
return TB ( "The path must not be empty. Please select a directory." );
2025-01-13 19:51:26 +01:00
if (! Directory . Exists ( path ))
2025-05-04 14:59:30 +02:00
return TB ( "The path does not exist. Please select a valid directory." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidateFilePath ( string filePath )
{
if ( string . IsNullOrWhiteSpace ( filePath ))
2025-05-04 14:59:30 +02:00
return TB ( "The file path must not be empty. Please select a file." );
2025-01-13 19:51:26 +01:00
if (! File . Exists ( filePath ))
2025-05-04 14:59:30 +02:00
return TB ( "The file does not exist. Please select a valid file." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidateEmbeddingId ( string embeddingId )
{
if ( string . IsNullOrWhiteSpace ( embeddingId ))
2025-05-04 14:59:30 +02:00
return TB ( "Please select an embedding provider." );
2025-01-13 19:51:26 +01:00
return null ;
}
2026-09-09 18:43:37 +02:00
public string? ValidateEmbeddingProviderAccess ( string embeddingId )
{
var embeddingIssue = this . ValidateEmbeddingId ( embeddingId );
return embeddingIssue ?? this . ValidateSelectedEmbeddingProviderAccess ();
}
public string? ValidateDataSourceConfidenceLevel ( ConfidenceLevel confidenceLevel )
{
if ( confidenceLevel is ConfidenceLevel . NONE )
return TB ( "Please select a required provider confidence level." );
return this . ValidateSelectedEmbeddingProviderAccess ();
}
2025-01-13 19:51:26 +01:00
public string? ValidateUserAcknowledgedCloudEmbedding ( bool value )
{
if ( this . GetSelectedCloudEmbedding () && ! value )
2025-05-04 14:59:30 +02:00
return TB ( "Please acknowledge that you are aware of the cloud embedding implications." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidateTestedConnection ()
{
if (! this . GetTestedConnection ())
2025-05-04 14:59:30 +02:00
return TB ( "Please test the connection before saving." );
2025-01-13 19:51:26 +01:00
if (! this . GetTestedConnectionResult ())
2025-05-04 14:59:30 +02:00
return TB ( "The connection test failed. Please check the connection settings." );
2025-01-13 19:51:26 +01:00
return null ;
}
public string? ValidateAuthMethod ( AuthMethod authMethod )
{
if (! this . GetAvailableAuthMethods (). Contains ( authMethod ))
2025-05-04 14:59:30 +02:00
return TB ( "Please select one valid authentication method." );
2025-01-13 19:51:26 +01:00
return null ;
}
2026-09-09 18:43:37 +02:00
private string? ValidateSelectedEmbeddingProviderAccess ()
{
var selectedEmbedding = this . GetSelectedEmbeddingProvider ();
var settingsManager = this . GetSettingsManager ();
if ( selectedEmbedding is null || settingsManager is null )
return null ;
var confidenceLevel = this . GetConfidenceLevel ();
if ( selectedEmbedding . GetConfidenceLevel ( settingsManager ). AllowsDataSourceConfidenceLevel ( confidenceLevel ))
return null ;
return string . Format (
TB ( "The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the required confidence level." ),
selectedEmbedding . GetConfidenceLevel ( settingsManager ). GetName (),
confidenceLevel . GetName ());
}
}