c22b4a2613
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
349 lines
11 KiB
Markdown
349 lines
11 KiB
Markdown
# 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
|