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,288 @@
|
||||
namespace CredentialManager.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Tipi di credenziali supportate
|
||||
/// </summary>
|
||||
public enum CredentialType
|
||||
{
|
||||
Database,
|
||||
RestApi,
|
||||
OAuth,
|
||||
ApiKey,
|
||||
BasicAuth
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipi di servizi REST specifici
|
||||
/// </summary>
|
||||
public enum RestServiceType
|
||||
{
|
||||
Generic,
|
||||
SapB1ServiceLayer,
|
||||
Salesforce
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipi di database supportati (allineato con DataConnection.Enums.DatabaseType)
|
||||
/// </summary>
|
||||
public enum DatabaseType
|
||||
{
|
||||
SqlServer,
|
||||
MySql,
|
||||
PostgreSql,
|
||||
Oracle,
|
||||
Sqlite,
|
||||
DB2,
|
||||
SapHana
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO per le credenziali database - completo per tutti i tipi di DB supportati
|
||||
/// </summary>
|
||||
public class DatabaseCredential
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public DatabaseType DatabaseType { get; set; }
|
||||
public string Host { get; set; } = string.Empty;
|
||||
public int Port { get; set; }
|
||||
public string? DatabaseName { get; set; } = string.Empty; // Ora opzionale
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string? ConnectionString { get; set; }
|
||||
public int CommandTimeout { get; set; } = 30;
|
||||
public bool IgnoreSslErrors { get; set; } = false;
|
||||
public Dictionary<string, string>? AdditionalParameters { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO per le credenziali REST API - allineato con RestServiceOptions e esteso per servizi specifici
|
||||
/// </summary>
|
||||
public class RestApiCredential
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public RestServiceType ServiceType { get; set; } = RestServiceType.Generic;
|
||||
public string BaseUrl { get; set; } = string.Empty;
|
||||
public string? ApiKey { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public string? Password { get; set; }
|
||||
public string? AuthToken { get; set; }
|
||||
public string? BearerToken { get; set; }
|
||||
public int TimeoutSeconds { get; set; } = 100;
|
||||
public bool IgnoreSslErrors { get; set; } = false;
|
||||
public Dictionary<string, string>? Headers { get; set; }
|
||||
public Dictionary<string, string>? AdditionalParameters { get; set; }
|
||||
|
||||
// Campi specifici per SAP B1 Service Layer
|
||||
public string? CompanyDatabase { get; set; }
|
||||
public string? Language { get; set; } = "en-US";
|
||||
public string? Version { get; set; } = "v1";
|
||||
public bool UseTrustedConnection { get; set; } = false;
|
||||
|
||||
// Campi specifici per Salesforce
|
||||
public string? SecurityToken { get; set; }
|
||||
public string? ClientId { get; set; }
|
||||
public string? ClientSecret { get; set; }
|
||||
public string? ApiVersion { get; set; } = "59.0";
|
||||
public bool IsSandbox { get; set; } = false;
|
||||
public bool UseSoapApi { get; set; } = false;
|
||||
public string? RefreshToken { get; set; }
|
||||
public string? AccessToken { get; set; }
|
||||
public DateTime? TokenExpiry { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Credenziali specifiche per SAP Business One Service Layer
|
||||
/// </summary>
|
||||
public class SapB1ServiceLayerCredential
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string ServerUrl { get; set; } = string.Empty; // es: https://server:50000/b1s/v1/
|
||||
public string CompanyDatabase { get; set; } = string.Empty; // Database dell'azienda SAP
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string? Language { get; set; } = "en-US"; // Lingua per la sessione
|
||||
public int TimeoutSeconds { get; set; } = 300; // Timeout per le chiamate API
|
||||
public bool IgnoreSslErrors { get; set; } = false;
|
||||
public string? Version { get; set; } = "v1"; // Versione del Service Layer (v1, v2, etc.)
|
||||
public bool UseTrustedConnection { get; set; } = false; // Per autenticazione Windows
|
||||
public Dictionary<string, string>? AdditionalHeaders { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Credenziali specifiche per Salesforce
|
||||
/// </summary>
|
||||
public class SalesforceCredential
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string LoginUrl { get; set; } = "https://login.salesforce.com"; // o https://test.salesforce.com per sandbox
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string SecurityToken { get; set; } = string.Empty; // Token di sicurezza Salesforce
|
||||
public string? ClientId { get; set; } = string.Empty; // Consumer Key per Connected App
|
||||
public string? ClientSecret { get; set; } = string.Empty; // Consumer Secret per Connected App
|
||||
public string ApiVersion { get; set; } = "59.0"; // Versione API Salesforce
|
||||
public bool IsSandbox { get; set; } = false; // Se è un ambiente sandbox
|
||||
public int TimeoutSeconds { get; set; } = 120;
|
||||
public bool UseSoapApi { get; set; } = false; // Se usare SOAP invece di REST
|
||||
public string? RefreshToken { get; set; }
|
||||
public string? AccessToken { get; set; }
|
||||
public DateTime? TokenExpiry { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory per creare connection string per i diversi tipi di database
|
||||
/// </summary>
|
||||
public static class ConnectionStringBuilder
|
||||
{
|
||||
public static string BuildConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(credential.ConnectionString))
|
||||
return credential.ConnectionString;
|
||||
|
||||
return credential.DatabaseType switch
|
||||
{
|
||||
DatabaseType.SqlServer => BuildSqlServerConnectionString(credential),
|
||||
DatabaseType.MySql => BuildMySqlConnectionString(credential),
|
||||
DatabaseType.PostgreSql => BuildPostgreSqlConnectionString(credential),
|
||||
DatabaseType.Oracle => BuildOracleConnectionString(credential),
|
||||
DatabaseType.Sqlite => BuildSqliteConnectionString(credential),
|
||||
DatabaseType.DB2 => BuildDb2ConnectionString(credential),
|
||||
DatabaseType.SapHana => BuildSapHanaConnectionString(credential),
|
||||
_ => throw new NotSupportedException($"Database type {credential.DatabaseType} not supported")
|
||||
};
|
||||
} private static string BuildSqlServerConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Server={credential.Host},{credential.Port}",
|
||||
$"User Id={credential.Username}",
|
||||
$"Password={credential.Password}",
|
||||
$"Connection Timeout={credential.CommandTimeout}"
|
||||
};
|
||||
|
||||
// Aggiungi Database solo se specificato
|
||||
if (!string.IsNullOrEmpty(credential.DatabaseName))
|
||||
builder.Add($"Database={credential.DatabaseName}");
|
||||
|
||||
if (credential.IgnoreSslErrors)
|
||||
builder.Add("TrustServerCertificate=True");
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
} private static string BuildMySqlConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Server={credential.Host}",
|
||||
$"Port={credential.Port}",
|
||||
$"Uid={credential.Username}",
|
||||
$"Pwd={credential.Password}",
|
||||
$"Connection Timeout={credential.CommandTimeout}"
|
||||
};
|
||||
|
||||
// Aggiungi Database solo se specificato
|
||||
if (!string.IsNullOrEmpty(credential.DatabaseName))
|
||||
builder.Add($"Database={credential.DatabaseName}");
|
||||
|
||||
if (credential.IgnoreSslErrors)
|
||||
builder.Add("SslMode=None");
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
} private static string BuildPostgreSqlConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Host={credential.Host}",
|
||||
$"Port={credential.Port}",
|
||||
$"Username={credential.Username}",
|
||||
$"Password={credential.Password}",
|
||||
$"Timeout={credential.CommandTimeout}"
|
||||
};
|
||||
|
||||
// Aggiungi Database solo se specificato
|
||||
if (!string.IsNullOrEmpty(credential.DatabaseName))
|
||||
builder.Add($"Database={credential.DatabaseName}");
|
||||
|
||||
if (credential.IgnoreSslErrors)
|
||||
builder.Add("SSL Mode=Disable");
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
} private static string BuildOracleConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>();
|
||||
|
||||
// Per Oracle, il formato cambia se c'è o meno un database specificato
|
||||
if (!string.IsNullOrEmpty(credential.DatabaseName))
|
||||
{
|
||||
builder.Add($"Data Source={credential.Host}:{credential.Port}/{credential.DatabaseName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Add($"Data Source={credential.Host}:{credential.Port}");
|
||||
}
|
||||
|
||||
builder.AddRange(new[]
|
||||
{
|
||||
$"User Id={credential.Username}",
|
||||
$"Password={credential.Password}",
|
||||
$"Connection Timeout={credential.CommandTimeout}"
|
||||
});
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
}
|
||||
|
||||
private static string BuildSqliteConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Data Source={credential.DatabaseName}"
|
||||
};
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
}
|
||||
|
||||
private static string BuildDb2ConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Server={credential.Host}:{credential.Port}",
|
||||
$"Database={credential.DatabaseName}",
|
||||
$"UID={credential.Username}",
|
||||
$"PWD={credential.Password}",
|
||||
$"Connection Timeout={credential.CommandTimeout}"
|
||||
};
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
}
|
||||
|
||||
private static string BuildSapHanaConnectionString(DatabaseCredential credential)
|
||||
{
|
||||
var builder = new List<string>
|
||||
{
|
||||
$"Server={credential.Host}:{credential.Port}",
|
||||
$"DatabaseName={credential.DatabaseName}",
|
||||
$"UserID={credential.Username}",
|
||||
$"Password={credential.Password}",
|
||||
$"Connection Timeout={credential.CommandTimeout}"
|
||||
};
|
||||
|
||||
AddAdditionalParameters(builder, credential.AdditionalParameters);
|
||||
return string.Join(";", builder);
|
||||
}
|
||||
|
||||
private static void AddAdditionalParameters(List<string> builder, Dictionary<string, string>? additionalParams)
|
||||
{
|
||||
if (additionalParams != null)
|
||||
{
|
||||
foreach (var param in additionalParams)
|
||||
{
|
||||
builder.Add($"{param.Key}={param.Value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user