# CredentialManager Un sistema sicuro per la gestione delle credenziali di database e API REST utilizzando Entity Framework Core e SQLite, specificamente progettato per integrarsi con il progetto DataConnection. ## Caratteristiche - ✅ Memorizzazione sicura delle credenziali con crittografia cross-platform - ✅ Supporto completo per tutti i database del progetto DataConnection: - SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA - ✅ Supporto per credenziali API REST (API Key, Basic Auth, Bearer Token) - ✅ Generazione automatica di connection string per tutti i tipi di database - ✅ Database SQLite con Entity Framework Core - ✅ Creazione automatica del database se non esiste - ✅ Logging integrato - ✅ Cross-platform (Windows, Linux, macOS) - ✅ Dependency Injection pronto - ✅ Validazione delle credenziali - ✅ Metodi di utilità per integrazione con DataConnection ## Tipi di Database Supportati Il CredentialManager supporta tutti i tipi di database gestiti dal progetto DataConnection: - **SQL Server** (porta predefinita: 1433) - **MySQL** (porta predefinita: 3306) - **PostgreSQL** (porta predefinita: 5432) - **Oracle** (porta predefinita: 1521) - **SQLite** (database locale) - **DB2** (porta predefinita: 50000) - **SAP HANA** (porta predefinita: 30015) ## Installazione 1. Aggiungi il progetto CredentialManager alla tua soluzione 2. Referenzia il progetto nel tuo progetto principale ## Utilizzo Base ### Utilizzo Standalone ```csharp using CredentialManager; using CredentialManager.Models; using CredentialManager.Integration; // Crea un'istanza del servizio var credentialService = await CredentialManagerFactory.CreateAsync(); // Salva una credenziale database con validazione var dbCredential = new DatabaseCredential { Name = "Database Produzione", DatabaseType = DatabaseType.SqlServer, Host = "sql-server.company.com", Port = 1433, // Si può omettere, verrà usata la porta predefinita DatabaseName = "ProductionDB", Username = "dbuser", Password = "secretpassword", CommandTimeout = 30, IgnoreSslErrors = false, AdditionalParameters = new Dictionary { ["Encrypt"] = "True", ["TrustServerCertificate"] = "True" } }; // Salva con validazione automatica var id = await credentialService.SaveValidatedDatabaseCredentialAsync(dbCredential); // Genera automaticamente la connection string var connectionString = dbCredential.ToConnectionString(); Console.WriteLine($"Connection String: {connectionString}"); ``` ### Integrazione con DataConnection ```csharp using CredentialManager.Integration; // Ottieni credenziale validata var credential = await credentialService.GetValidatedDatabaseCredentialAsync("Database Produzione"); // Converti per l'uso con DbManagerOptions var dbOptions = credential.ToDbManagerOptions(); // Oppure ottieni direttamente la connection string var connectionString = credential.ToConnectionString(); ``` ### Utilizzo con Dependency Injection ```csharp using CredentialManager; using Microsoft.Extensions.DependencyInjection; var services = new ServiceCollection(); // Registra i servizi services.AddLogging(builder => builder.AddConsole()); services.AddCredentialManager("path/to/credentials.db"); // Percorso opzionale var serviceProvider = services.BuildServiceProvider(); // Inizializza il database await serviceProvider.InitializeCredentialManagerAsync(); // Usa il servizio var credentialService = serviceProvider.GetRequiredService(); ``` ## Tipi di Credenziali Supportate ### Credenziali Database ```csharp var dbCredential = new DatabaseCredential { Name = "Nome Univoco", DatabaseType = DatabaseType.SqlServer, // Tutti i tipi supportati da DataConnection Host = "server.company.com", Port = 1433, // Opzionale, usa porta predefinita se omesso DatabaseName = "MyDatabase", Username = "dbuser", Password = "password", // Verrà crittata automaticamente ConnectionString = "Server=...", // Opzionale, stringa di connessione completa CommandTimeout = 30, // Timeout comandi in secondi IgnoreSslErrors = false, // Per connessioni SSL non verificate AdditionalParameters = new Dictionary { ["Encrypt"] = "True", ["TrustServerCertificate"] = "True" } }; await credentialService.SaveValidatedDatabaseCredentialAsync(dbCredential); ``` ### Credenziali REST API ```csharp var apiCredential = new RestApiCredential { Name = "API Esterna", BaseUrl = "https://api.external-service.com", ApiKey = "your-api-key", // Verrà crittata automaticamente Username = "apiuser", // Per Basic Auth Password = "apipass", // Per Basic Auth, verrà crittata AuthToken = "bearer-token", // Per Bearer Auth, verrà crittata TimeoutSeconds = 60, // Timeout richieste IgnoreSslErrors = false, // Per API con certificati non verificati Headers = new Dictionary { ["Content-Type"] = "application/json", ["Accept"] = "application/json" }, AdditionalParameters = new Dictionary { ["CustomParam"] = "value" } }; await credentialService.SaveValidatedRestApiCredentialAsync(apiCredential); ``` ## Generazione Connection String Il CredentialManager può generare automaticamente connection string per tutti i tipi di database: ```csharp // Genera connection string automaticamente var connectionString = credential.ToConnectionString(); // Connection string specifiche per tipo di database: // SQL Server: "Server=host,port;Database=dbname;User Id=user;Password=pass;Connection Timeout=30" // MySQL: "Server=host;Port=port;Database=dbname;Uid=user;Pwd=pass;Connection Timeout=30" // PostgreSQL: "Host=host;Port=port;Database=dbname;Username=user;Password=pass;Timeout=30" // Oracle: "Data Source=host:port/dbname;User Id=user;Password=pass;Connection Timeout=30" // SQLite: "Data Source=dbname" // DB2: "Server=host:port;Database=dbname;UID=user;PWD=pass;Connection Timeout=30" // SAP HANA: "Server=host:port;DatabaseName=dbname;UserID=user;Password=pass;Connection Timeout=30" ``` ## Validazione delle Credenziali ```csharp using CredentialManager.Integration; // Validazione manuale var errors = DataConnectionHelper.ValidateDatabaseCredential(credential); if (errors.Any()) { Console.WriteLine($"Errori: {string.Join(", ", errors)}"); } // Validazione automatica durante il salvataggio try { await credentialService.SaveValidatedDatabaseCredentialAsync(credential); } catch (ArgumentException ex) { Console.WriteLine($"Credenziale non valida: {ex.Message}"); } ``` ## Operazioni Principali ### Salvare Credenziali ```csharp // Con validazione automatica (raccomandato) var dbId = await credentialService.SaveValidatedDatabaseCredentialAsync(databaseCredential); var apiId = await credentialService.SaveValidatedRestApiCredentialAsync(apiCredential); // Senza validazione var dbId = await credentialService.SaveDatabaseCredentialAsync(databaseCredential); var apiId = await credentialService.SaveRestApiCredentialAsync(apiCredential); ``` ### Recuperare Credenziali ```csharp // Con validazione automatica (raccomandato) var dbCred = await credentialService.GetValidatedDatabaseCredentialAsync("Database Produzione"); var apiCred = await credentialService.GetValidatedRestApiCredentialAsync("API Esterna"); // Senza validazione var dbCred = await credentialService.GetDatabaseCredentialAsync("Database Produzione"); var apiCred = await credentialService.GetRestApiCredentialAsync("API Esterna"); // Per ID var dbCred = await credentialService.GetDatabaseCredentialAsync(1); var apiCred = await credentialService.GetRestApiCredentialAsync(2); // Tutte le credenziali di un tipo var allDbCreds = await credentialService.GetAllDatabaseCredentialsAsync(); var allApiCreds = await credentialService.GetAllRestApiCredentialsAsync(); ``` ### Eliminare Credenziali ```csharp // Per nome await credentialService.DeleteCredentialAsync("Nome Credenziale"); // Per ID await credentialService.DeleteCredentialAsync(1); ``` ### Ottenere Lista Nomi ```csharp // Tutti i nomi var allNames = await credentialService.GetCredentialNamesAsync(); // Solo nomi di un tipo specifico var dbNames = await credentialService.GetCredentialNamesAsync(CredentialType.Database); var apiNames = await credentialService.GetCredentialNamesAsync(CredentialType.RestApi); ``` ## Configurazione ### Percorso Database Personalizzato ```csharp // Specificare un percorso personalizzato per il database services.AddCredentialManager("/custom/path/credentials.db"); // O per utilizzo standalone var service = await CredentialManagerFactory.CreateAsync("/custom/path/credentials.db"); ``` ### Logging Personalizzato ```csharp var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Debug)); var service = await CredentialManagerFactory.CreateAsync( databasePath: "credentials.db", loggerFactory: loggerFactory); ``` ## Sicurezza - Le password, API key e token sono crittati utilizzando: - **Windows**: `ProtectedData` con entropia personalizzata - **Altri OS**: AES-256 con chiave derivata - I dati sono memorizzati localmente in un database SQLite - Le credenziali eliminate sono contrassegnate come inattive (soft delete) - Validazione automatica dei dati di input ## Struttura Database Il database SQLite viene creato automaticamente con la seguente struttura: ```sql CREATE TABLE Credentials ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Name NVARCHAR(100) NOT NULL UNIQUE, Type NVARCHAR(50) NOT NULL, DatabaseType NVARCHAR(50), Host NVARCHAR(200), Port INTEGER, DatabaseName NVARCHAR(100), Username NVARCHAR(100), EncryptedPassword TEXT, ConnectionString NVARCHAR(500), EncryptedApiKey NVARCHAR(500), EncryptedAuthToken NVARCHAR(500), CommandTimeout INTEGER DEFAULT 30, TimeoutSeconds INTEGER DEFAULT 100, IgnoreSslErrors INTEGER DEFAULT 0, Headers NVARCHAR(2000), AdditionalParameters NVARCHAR(2000), CreatedAt DATETIME NOT NULL, UpdatedAt DATETIME, CreatedBy NVARCHAR(100), IsActive INTEGER NOT NULL DEFAULT 1 ); ``` ## Porte Predefinite Il sistema assegna automaticamente le porte predefinite se non specificate: - SQL Server: 1433 - MySQL: 3306 - PostgreSQL: 5432 - Oracle: 1521 - DB2: 50000 - SAP HANA: 30015 - SQLite: N/A (database locale) ## Requisiti - .NET 9.0 - Entity Framework Core 9.0 - SQLite ## Note - Il database viene creato nella cartella `%APPDATA%/CredentialManager/` se non specificato un percorso personalizzato - Tutte le operazioni sono asincrone - Il servizio è thread-safe - Le migrazioni del database vengono applicate automaticamente all'avvio - Piena compatibilità con il progetto DataConnection