using CredentialManager.Models; using CredentialManager.Services; namespace CredentialManager.Integration; /// /// Metodi di utilità per l'integrazione con DataConnection /// public static class DataConnectionHelper { /// /// Converte una DatabaseCredential in una stringa di connessione /// /// La credenziale database /// Stringa di connessione pronta per l'uso public static string ToConnectionString(this DatabaseCredential credential) { return ConnectionStringBuilder.BuildConnectionString(credential); } /// /// Crea le opzioni per RestServiceOptions dal progetto DataConnection /// /// La credenziale REST API /// Oggetto con le opzioni per REST service public static object ToRestServiceOptions(this RestApiCredential credential) { return new { BaseUrl = credential.BaseUrl, ApiKey = credential.ApiKey, Username = credential.Username, Password = credential.Password, AuthToken = credential.AuthToken, TimeoutSeconds = credential.TimeoutSeconds, IgnoreSslErrors = credential.IgnoreSslErrors }; } /// /// Crea le opzioni per DbManagerOptions dal progetto DataConnection /// /// La credenziale database /// Oggetto con le opzioni per DB manager public static object ToDbManagerOptions(this DatabaseCredential credential) { return new { ServerConnectionString = credential.ToConnectionString(), DatabaseName = credential.DatabaseName, DatabaseType = credential.DatabaseType.ToString(), CommandTimeout = credential.CommandTimeout }; } /// /// Ottiene la porta predefinita per un tipo di database /// /// Tipo di database /// Porta predefinita public static int GetDefaultPort(DatabaseType databaseType) { return databaseType switch { DatabaseType.SqlServer => 1433, DatabaseType.MySql => 3306, DatabaseType.PostgreSql => 5432, DatabaseType.Oracle => 1521, DatabaseType.DB2 => 50000, DatabaseType.SapHana => 30015, DatabaseType.Sqlite => 0, // Non applicabile _ => 0 }; } /// /// Valida una credenziale database /// /// La credenziale da validare /// Lista di errori di validazione (vuota se valida) public static List ValidateDatabaseCredential(DatabaseCredential credential) { var errors = new List(); // Sorgenti file-based (percorso, senza host/utente/password/porta) bool isFileBased = credential.DatabaseType == DatabaseType.Sqlite || credential.DatabaseType == DatabaseType.Foxpro; if (string.IsNullOrWhiteSpace(credential.Name)) errors.Add("Il nome della credenziale è obbligatorio"); if (string.IsNullOrWhiteSpace(credential.Host) && !isFileBased) errors.Add("L'host è obbligatorio per questo tipo di database"); if (string.IsNullOrWhiteSpace(credential.DatabaseName)) errors.Add(credential.DatabaseType == DatabaseType.Foxpro ? "Il percorso del database FoxPro (.dbc o cartella .dbf) è obbligatorio" : "Il nome del database è obbligatorio"); if (string.IsNullOrWhiteSpace(credential.Username) && !isFileBased) errors.Add("Il nome utente è obbligatorio per questo tipo di database"); if (string.IsNullOrWhiteSpace(credential.Password) && !isFileBased) errors.Add("La password è obbligatoria per questo tipo di database"); if (credential.Port <= 0 && !isFileBased) { // Assegna porta predefinita se non specificata credential.Port = GetDefaultPort(credential.DatabaseType); } return errors; } /// /// Valida una credenziale REST API /// /// La credenziale da validare /// Lista di errori di validazione (vuota se valida) public static List ValidateRestApiCredential(RestApiCredential credential) { var errors = new List(); if (string.IsNullOrWhiteSpace(credential.Name)) errors.Add("Il nome della credenziale è obbligatorio"); if (string.IsNullOrWhiteSpace(credential.BaseUrl)) errors.Add("L'URL base è obbligatorio"); else if (!Uri.TryCreate(credential.BaseUrl, UriKind.Absolute, out _)) errors.Add("L'URL base non è valido"); // Almeno uno tra ApiKey, Username/Password, o AuthToken deve essere specificato var hasApiKey = !string.IsNullOrWhiteSpace(credential.ApiKey); var hasUserPass = !string.IsNullOrWhiteSpace(credential.Username) && !string.IsNullOrWhiteSpace(credential.Password); var hasAuthToken = !string.IsNullOrWhiteSpace(credential.AuthToken); if (!hasApiKey && !hasUserPass && !hasAuthToken) errors.Add("Deve essere specificato almeno un metodo di autenticazione (API Key, Username/Password, o Auth Token)"); return errors; } } /// /// Estensioni per la gestione asincrona delle credenziali /// public static class CredentialServiceExtensions { /// /// Ottiene una credenziale database validata /// /// Il servizio credenziali /// Nome della credenziale /// Credenziale validata o null se non trovata public static async Task GetValidatedDatabaseCredentialAsync( this ICredentialService service, string name) { var credential = await service.GetDatabaseCredentialAsync(name); if (credential == null) return null; var errors = DataConnectionHelper.ValidateDatabaseCredential(credential); if (errors.Any()) throw new ArgumentException($"Credenziale non valida: {string.Join(", ", errors)}"); return credential; } /// /// Ottiene una credenziale REST API validata /// /// Il servizio credenziali /// Nome della credenziale /// Credenziale validata o null se non trovata public static async Task GetValidatedRestApiCredentialAsync( this ICredentialService service, string name) { var credential = await service.GetRestApiCredentialAsync(name); if (credential == null) return null; var errors = DataConnectionHelper.ValidateRestApiCredential(credential); if (errors.Any()) throw new ArgumentException($"Credenziale non valida: {string.Join(", ", errors)}"); return credential; } /// /// Salva una credenziale database con validazione /// /// Il servizio credenziali /// La credenziale da salvare /// ID della credenziale salvata public static async Task SaveValidatedDatabaseCredentialAsync( this ICredentialService service, DatabaseCredential credential) { var errors = DataConnectionHelper.ValidateDatabaseCredential(credential); if (errors.Any()) throw new ArgumentException($"Credenziale non valida: {string.Join(", ", errors)}"); return await service.SaveDatabaseCredentialAsync(credential); } /// /// Salva una credenziale REST API con validazione /// /// Il servizio credenziali /// La credenziale da salvare /// ID della credenziale salvata public static async Task SaveValidatedRestApiCredentialAsync( this ICredentialService service, RestApiCredential credential) { var errors = DataConnectionHelper.ValidateRestApiCredential(credential); if (errors.Any()) throw new ArgumentException($"Credenziale non valida: {string.Join(", ", errors)}"); return await service.SaveRestApiCredentialAsync(credential); } }