feat: Integrazione completa gestione credenziali per database e REST API con supporto SAP B1 e Salesforce
NUOVE FUNZIONALITÀ: - Aggiunto modulo CredentialManager per gestione centralizzata credenziali - Implementata UI Blazor per gestione credenziali (CredentialManagement.razor) - Supporto completo per credenziali database (SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA) - Gestione unificata REST API con supporto specifico per SAP B1 Service Layer e Salesforce - Test reali di connessione per database, SAP B1 e Salesforce OAuth2 - Selezione dinamica tipo servizio REST (Generico, SAP B1, Salesforce) con campi specifici - Persistenza sicura di credenziali con crittografia password e campi sensibili COMPONENTI AGGIUNTI: - CredentialManager/Models/: CredentialEntity, CredentialModels (DatabaseCredential, RestApiCredential, SapB1ServiceLayerCredential, SalesforceCredential) - CredentialManager/Services/: CredentialService, EncryptionService, DatabaseInitializer - CredentialManager/Data/: CredentialDbContext con Entity Framework - DataConnection/CredentialManagement/: Interfacce e servizi di integrazione - Data_Coupler/Pages/CredentialManagement.razor: UI completa per gestione credenziali MIGLIORAMENTI UI: - Form dinamica per REST API con campi specifici per tipo servizio - Validazione campi obbligatori per Salesforce (ClientId, ClientSecret, SecurityToken) - Test connessione in tempo reale dalla modale di inserimento/modifica - Rimozione sezioni separate per SAP B1 e Salesforce (ora unificate in REST API) - Gestione stato loading durante operazioni async PERSISTENZA AVANZATA: - Campo RestServiceType aggiunto a CredentialEntity con migrazione automatica - Serializzazione campi specifici Salesforce/SAP B1 in AdditionalParameters JSON - Mapping bidirezionale tra entità database e modelli business - Gestione nullability e conversioni tipo sicure SICUREZZA: - Crittografia AES-256 per password e token sensibili - Gestione sicura ConnectionString database - Validazione input e sanitizzazione dati TESTING E CONNETTIVITÀ: - Test autenticazione reale SAP B1 Service Layer - Test OAuth2 Salesforce con supporto Connected App - Test connettività database multi-provider - Logging dettagliato per debugging e monitoraggio CONFIGURAZIONE: - Dependency injection per tutti i servizi - Configurazione Entity Framework con SQLite - Tasks VS Code per build e run - Gestione connection string centralizzata CORREZIONI: - Risolti errori nullability in CredentialService - Aggiunto using Microsoft.JSInterop per IJSRuntime - Fix compilazione e warning Files modificati: 35+ file tra nuovi e aggiornati
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
# 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<string, string>
|
||||
{
|
||||
["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<ICredentialService>();
|
||||
```
|
||||
|
||||
## 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<string, string>
|
||||
{
|
||||
["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<string, string>
|
||||
{
|
||||
["Content-Type"] = "application/json",
|
||||
["Accept"] = "application/json"
|
||||
},
|
||||
AdditionalParameters = new Dictionary<string, string>
|
||||
{
|
||||
["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
|
||||
Reference in New Issue
Block a user