using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using CredentialManager.Data;
using CredentialManager.Models;
using System.Text.Json;
namespace CredentialManager.Services;
///
/// Interfaccia per il servizio di gestione credenziali
///
public interface ICredentialService
{
// Database Credentials
Task SaveDatabaseCredentialAsync(DatabaseCredential credential);
Task GetDatabaseCredentialAsync(string name);
Task GetDatabaseCredentialAsync(int id);
Task> GetAllDatabaseCredentialsAsync();
// REST API Credentials
Task SaveRestApiCredentialAsync(RestApiCredential credential);
Task GetRestApiCredentialAsync(string name);
Task GetRestApiCredentialAsync(int id);
Task> GetAllRestApiCredentialsAsync();
// SAP B1 Service Layer Credentials
Task SaveSapB1CredentialAsync(SapB1ServiceLayerCredential credential);
Task GetSapB1CredentialAsync(string name);
Task GetSapB1CredentialAsync(int id);
Task> GetAllSapB1CredentialsAsync();
// Salesforce Credentials
Task SaveSalesforceCredentialAsync(SalesforceCredential credential);
Task GetSalesforceCredentialAsync(string name);
Task GetSalesforceCredentialAsync(int id);
Task> GetAllSalesforceCredentialsAsync();
// Generic operations
Task DeleteCredentialAsync(int id);
Task DeleteCredentialAsync(string name);
Task> GetCredentialNamesAsync(CredentialType? type = null);
}
///
/// Servizio per la gestione delle credenziali
///
public class CredentialService : ICredentialService
{
private readonly CredentialDbContext _context;
private readonly IEncryptionService _encryptionService;
private readonly ILogger _logger;
public CredentialService(
CredentialDbContext context,
IEncryptionService encryptionService,
ILogger logger)
{
_context = context;
_encryptionService = encryptionService;
_logger = logger;
}
#region Database Credentials
public async Task SaveDatabaseCredentialAsync(DatabaseCredential credential)
{
try
{
var entity = new CredentialEntity
{
Name = credential.Name,
Type = CredentialType.Database.ToString(),
DatabaseType = credential.DatabaseType.ToString(),
Host = credential.Host,
Port = credential.Port,
DatabaseName = credential.DatabaseName,
Username = credential.Username,
EncryptedPassword = _encryptionService.Encrypt(credential.Password),
ConnectionString = credential.ConnectionString,
CommandTimeout = credential.CommandTimeout,
IgnoreSslErrors = credential.IgnoreSslErrors,
AdditionalParameters = credential.AdditionalParameters != null
? JsonSerializer.Serialize(credential.AdditionalParameters)
: null,
CreatedAt = DateTime.UtcNow,
CreatedBy = Environment.UserName
};
// Verifica se esiste già una credenziale con lo stesso nome
var existing = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == credential.Name);
if (existing != null)
{
// Aggiorna esistente
existing.DatabaseType = entity.DatabaseType;
existing.Host = entity.Host;
existing.Port = entity.Port;
existing.DatabaseName = entity.DatabaseName;
existing.Username = entity.Username;
existing.EncryptedPassword = entity.EncryptedPassword;
existing.ConnectionString = entity.ConnectionString;
existing.CommandTimeout = entity.CommandTimeout;
existing.IgnoreSslErrors = entity.IgnoreSslErrors;
existing.AdditionalParameters = entity.AdditionalParameters;
existing.UpdatedAt = DateTime.UtcNow;
_context.Credentials.Update(existing);
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale database aggiornata: {Name}", credential.Name);
return existing.Id;
}
else
{
// Crea nuovo
_context.Credentials.Add(entity);
await _context.SaveChangesAsync();
_logger.LogInformation("Nuova credenziale database salvata: {Name}", credential.Name);
return entity.Id;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel salvare la credenziale database: {Name}", credential.Name);
throw;
}
}
public async Task GetDatabaseCredentialAsync(string name)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == name && c.Type == CredentialType.Database.ToString() && c.IsActive);
return entity != null ? MapToDatabaseCredential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale database: {Name}", name);
throw;
}
}
public async Task GetDatabaseCredentialAsync(int id)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Id == id && c.Type == CredentialType.Database.ToString() && c.IsActive);
return entity != null ? MapToDatabaseCredential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale database: {Id}", id);
throw;
}
}
public async Task> GetAllDatabaseCredentialsAsync()
{
try
{
var entities = await _context.Credentials
.Where(c => c.Type == CredentialType.Database.ToString() && c.IsActive)
.ToListAsync();
return entities.Select(MapToDatabaseCredential).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare tutte le credenziali database");
throw;
}
}
#endregion
#region REST API Credentials
public async Task SaveRestApiCredentialAsync(RestApiCredential credential)
{
try
{
// Prepara i parametri aggiuntivi per includere i campi specifici del servizio
var additionalParams = new Dictionary();
// Copia i parametri aggiuntivi esistenti
if (credential.AdditionalParameters != null)
{
foreach (var param in credential.AdditionalParameters)
{
additionalParams[param.Key] = param.Value;
}
}
// Aggiungi campi specifici per SAP B1
if (credential.ServiceType == RestServiceType.SapB1ServiceLayer)
{
if (!string.IsNullOrEmpty(credential.CompanyDatabase))
additionalParams["CompanyDatabase"] = credential.CompanyDatabase;
if (!string.IsNullOrEmpty(credential.Language))
additionalParams["Language"] = credential.Language;
if (!string.IsNullOrEmpty(credential.Version))
additionalParams["Version"] = credential.Version;
additionalParams["UseTrustedConnection"] = credential.UseTrustedConnection.ToString();
}
// Aggiungi campi specifici per Salesforce
if (credential.ServiceType == RestServiceType.Salesforce)
{
if (!string.IsNullOrEmpty(credential.SecurityToken))
additionalParams["SecurityToken"] = credential.SecurityToken;
if (!string.IsNullOrEmpty(credential.ClientId))
additionalParams["ClientId"] = credential.ClientId;
if (!string.IsNullOrEmpty(credential.ClientSecret))
additionalParams["ClientSecret"] = credential.ClientSecret;
if (!string.IsNullOrEmpty(credential.ApiVersion))
additionalParams["ApiVersion"] = credential.ApiVersion;
additionalParams["IsSandbox"] = credential.IsSandbox.ToString();
additionalParams["UseSoapApi"] = credential.UseSoapApi.ToString();
if (!string.IsNullOrEmpty(credential.RefreshToken))
additionalParams["RefreshToken"] = credential.RefreshToken;
if (!string.IsNullOrEmpty(credential.AccessToken))
additionalParams["AccessToken"] = credential.AccessToken;
if (credential.TokenExpiry.HasValue)
additionalParams["TokenExpiry"] = credential.TokenExpiry.Value.ToString("O");
}
var entity = new CredentialEntity
{
Name = credential.Name,
Type = CredentialType.RestApi.ToString(),
RestServiceType = credential.ServiceType.ToString(),
Host = credential.BaseUrl,
Username = credential.Username,
EncryptedPassword = !string.IsNullOrEmpty(credential.Password)
? _encryptionService.Encrypt(credential.Password)
: null,
EncryptedApiKey = !string.IsNullOrEmpty(credential.ApiKey)
? _encryptionService.Encrypt(credential.ApiKey)
: null,
EncryptedAuthToken = !string.IsNullOrEmpty(credential.AuthToken)
? _encryptionService.Encrypt(credential.AuthToken)
: null,
TimeoutSeconds = credential.TimeoutSeconds,
IgnoreSslErrors = credential.IgnoreSslErrors,
Headers = credential.Headers != null
? JsonSerializer.Serialize(credential.Headers)
: null,
AdditionalParameters = additionalParams.Count > 0
? JsonSerializer.Serialize(additionalParams)
: null,
CreatedAt = DateTime.UtcNow,
CreatedBy = Environment.UserName
};
// Verifica se esiste già una credenziale con lo stesso nome
var existing = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == credential.Name);
if (existing != null)
{
// Aggiorna esistente
existing.RestServiceType = entity.RestServiceType;
existing.Host = entity.Host;
existing.Username = entity.Username;
existing.EncryptedPassword = entity.EncryptedPassword;
existing.EncryptedApiKey = entity.EncryptedApiKey;
existing.EncryptedAuthToken = entity.EncryptedAuthToken;
existing.TimeoutSeconds = entity.TimeoutSeconds;
existing.IgnoreSslErrors = entity.IgnoreSslErrors;
existing.Headers = entity.Headers;
existing.AdditionalParameters = entity.AdditionalParameters;
existing.UpdatedAt = DateTime.UtcNow;
_context.Credentials.Update(existing);
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale REST API aggiornata: {Name}", credential.Name);
return existing.Id;
}
else
{
// Crea nuovo
_context.Credentials.Add(entity);
await _context.SaveChangesAsync();
_logger.LogInformation("Nuova credenziale REST API salvata: {Name}", credential.Name);
return entity.Id;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel salvare la credenziale REST API: {Name}", credential.Name);
throw;
}
}
public async Task GetRestApiCredentialAsync(string name)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == name && c.Type == CredentialType.RestApi.ToString() && c.IsActive);
return entity != null ? MapToRestApiCredential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale REST API: {Name}", name);
throw;
}
}
public async Task GetRestApiCredentialAsync(int id)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Id == id && c.Type == CredentialType.RestApi.ToString() && c.IsActive);
return entity != null ? MapToRestApiCredential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale REST API: {Id}", id);
throw;
}
}
public async Task> GetAllRestApiCredentialsAsync()
{
try
{
var entities = await _context.Credentials
.Where(c => c.Type == CredentialType.RestApi.ToString() && c.IsActive)
.ToListAsync();
return entities.Select(MapToRestApiCredential).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare tutte le credenziali REST API");
throw;
}
}
#endregion
#region SAP B1 Service Layer Credentials
public async Task SaveSapB1CredentialAsync(SapB1ServiceLayerCredential credential)
{
try
{
// Controlla se esiste già una credenziale con lo stesso nome
var existingEntity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == credential.Name && c.Type == CredentialType.RestApi.ToString());
CredentialEntity entity;
if (existingEntity != null)
{
entity = existingEntity;
_logger.LogInformation("Aggiornamento credenziale SAP B1 esistente: {Name}", credential.Name);
}
else
{
entity = new CredentialEntity();
_context.Credentials.Add(entity);
_logger.LogInformation("Creazione nuova credenziale SAP B1: {Name}", credential.Name);
}
// Popola i campi dell'entità
entity.Name = credential.Name;
entity.Type = CredentialType.RestApi.ToString();
entity.RestServiceType = RestServiceType.SapB1ServiceLayer.ToString();
entity.Host = credential.ServerUrl;
entity.Username = credential.Username;
entity.EncryptedPassword = _encryptionService.Encrypt(credential.Password);
entity.TimeoutSeconds = credential.TimeoutSeconds;
entity.IgnoreSslErrors = credential.IgnoreSslErrors;
entity.Headers = credential.AdditionalHeaders != null
? JsonSerializer.Serialize(credential.AdditionalHeaders)
: null;
// Salva parametri aggiuntivi specifici per SAP B1
var additionalParams = new Dictionary
{
["CompanyDatabase"] = credential.CompanyDatabase,
["Language"] = credential.Language ?? "en-US",
["Version"] = credential.Version ?? "v1",
["UseTrustedConnection"] = credential.UseTrustedConnection.ToString()
};
entity.AdditionalParameters = JsonSerializer.Serialize(additionalParams);
entity.CreatedAt = existingEntity?.CreatedAt ?? DateTime.UtcNow;
entity.CreatedBy = existingEntity?.CreatedBy ?? Environment.UserName;
entity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale SAP B1 salvata con ID: {Id}", entity.Id);
return entity.Id;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel salvare la credenziale SAP B1: {Name}", credential.Name);
throw;
}
}
public async Task GetSapB1CredentialAsync(string name)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == name &&
c.Type == CredentialType.RestApi.ToString() &&
c.RestServiceType == RestServiceType.SapB1ServiceLayer.ToString() &&
c.IsActive);
return entity != null ? MapToSapB1Credential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale SAP B1: {Name}", name);
throw;
}
}
public async Task GetSapB1CredentialAsync(int id)
{
try
{
var entity = await _context.Credentials.FindAsync(id);
if (entity == null ||
entity.Type != CredentialType.RestApi.ToString() ||
entity.RestServiceType != RestServiceType.SapB1ServiceLayer.ToString() ||
!entity.IsActive)
return null;
return MapToSapB1Credential(entity);
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale SAP B1 con ID: {Id}", id);
throw;
}
}
public async Task> GetAllSapB1CredentialsAsync()
{
try
{
var entities = await _context.Credentials
.Where(c => c.Type == CredentialType.RestApi.ToString() &&
c.RestServiceType == RestServiceType.SapB1ServiceLayer.ToString() &&
c.IsActive)
.ToListAsync();
return entities.Select(MapToSapB1Credential).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare tutte le credenziali SAP B1");
throw;
}
}
#endregion
#region Salesforce Credentials
public async Task SaveSalesforceCredentialAsync(SalesforceCredential credential)
{
try
{
// Controlla se esiste già una credenziale con lo stesso nome
var existingEntity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == credential.Name && c.Type == CredentialType.RestApi.ToString());
CredentialEntity entity;
if (existingEntity != null)
{
entity = existingEntity;
_logger.LogInformation("Aggiornamento credenziale Salesforce esistente: {Name}", credential.Name);
}
else
{
entity = new CredentialEntity();
_context.Credentials.Add(entity);
_logger.LogInformation("Creazione nuova credenziale Salesforce: {Name}", credential.Name);
}
// Popola i campi dell'entità
entity.Name = credential.Name;
entity.Type = CredentialType.RestApi.ToString();
entity.RestServiceType = RestServiceType.Salesforce.ToString();
entity.Host = credential.LoginUrl;
entity.Username = credential.Username;
entity.EncryptedPassword = _encryptionService.Encrypt(credential.Password);
entity.TimeoutSeconds = credential.TimeoutSeconds;
// Salva parametri aggiuntivi specifici per Salesforce
var additionalParams = new Dictionary
{
["SecurityToken"] = credential.SecurityToken,
["ApiVersion"] = credential.ApiVersion,
["IsSandbox"] = credential.IsSandbox.ToString(),
["UseSoapApi"] = credential.UseSoapApi.ToString()
};
// Aggiungi ClientId e ClientSecret se forniti
if (!string.IsNullOrEmpty(credential.ClientId))
additionalParams["ClientId"] = credential.ClientId;
if (!string.IsNullOrEmpty(credential.ClientSecret))
additionalParams["ClientSecret"] = credential.ClientSecret;
if (!string.IsNullOrEmpty(credential.RefreshToken))
additionalParams["RefreshToken"] = credential.RefreshToken;
if (!string.IsNullOrEmpty(credential.AccessToken))
additionalParams["AccessToken"] = credential.AccessToken;
if (credential.TokenExpiry.HasValue)
additionalParams["TokenExpiry"] = credential.TokenExpiry.Value.ToString("O");
entity.AdditionalParameters = JsonSerializer.Serialize(additionalParams);
entity.CreatedAt = existingEntity?.CreatedAt ?? DateTime.UtcNow;
entity.CreatedBy = existingEntity?.CreatedBy ?? Environment.UserName;
entity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale Salesforce salvata con ID: {Id}", entity.Id);
return entity.Id;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel salvare la credenziale Salesforce: {Name}", credential.Name);
throw;
}
}
public async Task GetSalesforceCredentialAsync(string name)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == name &&
c.Type == CredentialType.RestApi.ToString() &&
c.RestServiceType == RestServiceType.Salesforce.ToString() &&
c.IsActive);
return entity != null ? MapToSalesforceCredential(entity) : null;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale Salesforce: {Name}", name);
throw;
}
}
public async Task GetSalesforceCredentialAsync(int id)
{
try
{
var entity = await _context.Credentials.FindAsync(id);
if (entity == null ||
entity.Type != CredentialType.RestApi.ToString() ||
entity.RestServiceType != RestServiceType.Salesforce.ToString() ||
!entity.IsActive)
return null;
return MapToSalesforceCredential(entity);
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare la credenziale Salesforce con ID: {Id}", id);
throw;
}
}
public async Task> GetAllSalesforceCredentialsAsync()
{
try
{
var entities = await _context.Credentials
.Where(c => c.Type == CredentialType.RestApi.ToString() &&
c.RestServiceType == RestServiceType.Salesforce.ToString() &&
c.IsActive)
.ToListAsync();
return entities.Select(MapToSalesforceCredential).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nel recuperare tutte le credenziali Salesforce");
throw;
}
}
#endregion
#region Generic Operations
public async Task DeleteCredentialAsync(int id)
{
try
{
var entity = await _context.Credentials.FindAsync(id);
if (entity == null) return false;
entity.IsActive = false;
entity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale eliminata (soft delete): {Name} (ID: {Id})", entity.Name, entity.Id);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nell'eliminare la credenziale con ID: {Id}", id);
throw;
}
}
public async Task DeleteCredentialAsync(string name)
{
try
{
var entity = await _context.Credentials
.FirstOrDefaultAsync(c => c.Name == name && c.IsActive);
if (entity == null) return false;
entity.IsActive = false;
entity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
_logger.LogInformation("Credenziale eliminata (soft delete): {Name} (ID: {Id})", entity.Name, entity.Id);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nell'eliminare la credenziale: {Name}", name);
throw;
}
}
public async Task> GetCredentialNamesAsync(CredentialType? type = null)
{
try
{
var query = _context.Credentials.Where(c => c.IsActive);
if (type.HasValue)
query = query.Where(c => c.Type == type.ToString());
return await query.Select(c => c.Name).ToListAsync();
}
catch (Exception ex)
{ _logger.LogError(ex, "Errore nel recuperare i nomi delle credenziali");
throw;
}
}
#endregion
#region Private Mapping Methods
private DatabaseCredential MapToDatabaseCredential(CredentialEntity entity)
{
var credential = new DatabaseCredential
{
Name = entity.Name,
DatabaseType = Enum.Parse(entity.DatabaseType!),
Host = entity.Host ?? string.Empty,
Port = entity.Port ?? 0,
DatabaseName = entity.DatabaseName ?? string.Empty,
Username = entity.Username ?? string.Empty,
Password = DecryptSafely(entity.EncryptedPassword, entity.Name, "password"),
ConnectionString = entity.ConnectionString,
CommandTimeout = entity.CommandTimeout,
IgnoreSslErrors = entity.IgnoreSslErrors
};
if (!string.IsNullOrEmpty(entity.AdditionalParameters))
{
try
{
credential.AdditionalParameters = JsonSerializer.Deserialize>(entity.AdditionalParameters);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare i parametri aggiuntivi per {Name}", entity.Name);
}
}
return credential;
}
private RestApiCredential MapToRestApiCredential(CredentialEntity entity)
{
var credential = new RestApiCredential
{
Name = entity.Name,
ServiceType = Enum.TryParse(entity.RestServiceType, out var serviceType)
? serviceType
: RestServiceType.Generic,
BaseUrl = entity.Host ?? string.Empty,
Username = entity.Username, Password = !string.IsNullOrEmpty(entity.EncryptedPassword)
? DecryptSafely(entity.EncryptedPassword, entity.Name, "password")
: null,
ApiKey = !string.IsNullOrEmpty(entity.EncryptedApiKey)
? DecryptSafely(entity.EncryptedApiKey, entity.Name, "API key")
: null,
AuthToken = !string.IsNullOrEmpty(entity.EncryptedAuthToken)
? DecryptSafely(entity.EncryptedAuthToken, entity.Name, "auth token")
: null,
TimeoutSeconds = entity.TimeoutSeconds,
IgnoreSslErrors = entity.IgnoreSslErrors
};
if (!string.IsNullOrEmpty(entity.Headers))
{
try
{
credential.Headers = JsonSerializer.Deserialize>(entity.Headers);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare gli headers per {Name}", entity.Name);
}
}
if (!string.IsNullOrEmpty(entity.AdditionalParameters))
{
try
{
var additionalParams = JsonSerializer.Deserialize>(entity.AdditionalParameters);
if (additionalParams != null)
{
// Imposta i parametri aggiuntivi generici
credential.AdditionalParameters = new Dictionary();
// Mappa i campi specifici per SAP B1
if (credential.ServiceType == RestServiceType.SapB1ServiceLayer)
{
if (additionalParams.TryGetValue("CompanyDatabase", out var companyDb))
credential.CompanyDatabase = companyDb;
if (additionalParams.TryGetValue("Language", out var language))
credential.Language = language;
if (additionalParams.TryGetValue("Version", out var version))
credential.Version = version;
if (additionalParams.TryGetValue("UseTrustedConnection", out var useTrusted) && bool.TryParse(useTrusted, out var trusted))
credential.UseTrustedConnection = trusted;
}
// Mappa i campi specifici per Salesforce
else if (credential.ServiceType == RestServiceType.Salesforce)
{
if (additionalParams.TryGetValue("SecurityToken", out var securityToken))
credential.SecurityToken = securityToken;
if (additionalParams.TryGetValue("ClientId", out var clientId))
credential.ClientId = clientId;
if (additionalParams.TryGetValue("ClientSecret", out var clientSecret))
credential.ClientSecret = clientSecret;
if (additionalParams.TryGetValue("ApiVersion", out var apiVersion))
credential.ApiVersion = apiVersion;
if (additionalParams.TryGetValue("IsSandbox", out var isSandbox) && bool.TryParse(isSandbox, out var sandbox))
credential.IsSandbox = sandbox;
if (additionalParams.TryGetValue("UseSoapApi", out var useSoap) && bool.TryParse(useSoap, out var soap))
credential.UseSoapApi = soap;
if (additionalParams.TryGetValue("RefreshToken", out var refreshToken))
credential.RefreshToken = refreshToken;
if (additionalParams.TryGetValue("AccessToken", out var accessToken))
credential.AccessToken = accessToken;
if (additionalParams.TryGetValue("TokenExpiry", out var tokenExpiry) && DateTime.TryParse(tokenExpiry, out var expiry))
credential.TokenExpiry = expiry;
}
// Copia tutti i parametri che non sono specifici del servizio
var serviceSpecificKeys = new HashSet
{
"CompanyDatabase", "Language", "Version", "UseTrustedConnection",
"SecurityToken", "ClientId", "ClientSecret", "ApiVersion",
"IsSandbox", "UseSoapApi", "RefreshToken", "AccessToken", "TokenExpiry"
};
foreach (var param in additionalParams)
{
if (!serviceSpecificKeys.Contains(param.Key))
{
credential.AdditionalParameters[param.Key] = param.Value;
}
}
// Se non ci sono parametri aggiuntivi generici, imposta a null
if (credential.AdditionalParameters.Count == 0)
credential.AdditionalParameters = null;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare i parametri aggiuntivi per {Name}", entity.Name);
}
}
return credential;
}
private SapB1ServiceLayerCredential MapToSapB1Credential(CredentialEntity entity)
{
var credential = new SapB1ServiceLayerCredential
{
Name = entity.Name,
ServerUrl = entity.Host ?? string.Empty,
Username = entity.Username ?? string.Empty,
Password = !string.IsNullOrEmpty(entity.EncryptedPassword)
? _encryptionService.Decrypt(entity.EncryptedPassword)
: string.Empty,
TimeoutSeconds = entity.TimeoutSeconds,
IgnoreSslErrors = entity.IgnoreSslErrors
};
if (!string.IsNullOrEmpty(entity.Headers))
{
try
{
credential.AdditionalHeaders = JsonSerializer.Deserialize>(entity.Headers);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare gli headers per SAP B1 {Name}", entity.Name);
}
}
if (!string.IsNullOrEmpty(entity.AdditionalParameters))
{
try
{
var additionalParams = JsonSerializer.Deserialize>(entity.AdditionalParameters);
if (additionalParams != null)
{
if (additionalParams.TryGetValue("CompanyDatabase", out var companyDb))
credential.CompanyDatabase = companyDb;
if (additionalParams.TryGetValue("Language", out var language))
credential.Language = language;
if (additionalParams.TryGetValue("Version", out var version))
credential.Version = version;
if (additionalParams.TryGetValue("UseTrustedConnection", out var useTrusted) && bool.TryParse(useTrusted, out var trusted))
credential.UseTrustedConnection = trusted;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare i parametri aggiuntivi per SAP B1 {Name}", entity.Name);
}
}
return credential;
}
private SalesforceCredential MapToSalesforceCredential(CredentialEntity entity)
{
var credential = new SalesforceCredential
{
Name = entity.Name,
LoginUrl = entity.Host ?? "https://login.salesforce.com",
Username = entity.Username ?? string.Empty,
Password = !string.IsNullOrEmpty(entity.EncryptedPassword)
? _encryptionService.Decrypt(entity.EncryptedPassword)
: string.Empty,
TimeoutSeconds = entity.TimeoutSeconds
};
if (!string.IsNullOrEmpty(entity.AdditionalParameters))
{
try
{
var additionalParams = JsonSerializer.Deserialize>(entity.AdditionalParameters);
if (additionalParams != null)
{
if (additionalParams.TryGetValue("SecurityToken", out var securityToken))
credential.SecurityToken = securityToken;
if (additionalParams.TryGetValue("ClientId", out var clientId))
credential.ClientId = clientId;
if (additionalParams.TryGetValue("ClientSecret", out var clientSecret))
credential.ClientSecret = clientSecret;
if (additionalParams.TryGetValue("ApiVersion", out var apiVersion))
credential.ApiVersion = apiVersion;
if (additionalParams.TryGetValue("IsSandbox", out var isSandbox) && bool.TryParse(isSandbox, out var sandbox))
credential.IsSandbox = sandbox;
if (additionalParams.TryGetValue("UseSoapApi", out var useSoap) && bool.TryParse(useSoap, out var soap))
credential.UseSoapApi = soap;
if (additionalParams.TryGetValue("RefreshToken", out var refreshToken))
credential.RefreshToken = refreshToken;
if (additionalParams.TryGetValue("AccessToken", out var accessToken))
credential.AccessToken = accessToken;
if (additionalParams.TryGetValue("TokenExpiry", out var tokenExpiry) && DateTime.TryParse(tokenExpiry, out var expiry))
credential.TokenExpiry = expiry;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Errore nel deserializzare i parametri aggiuntivi per Salesforce {Name}", entity.Name);
}
}
return credential;
}
#endregion
#region Private Utility Methods ///
/// Decrittografa in modo sicuro gestendo i fallimenti dovuti a migrazione tra macchine
///
/// Valore crittografato
/// Nome della credenziale per logging
/// Nome del campo per logging
/// Valore decrittografato o stringa speciale per indicare che serve re-inserimento
private string DecryptSafely(string? encryptedValue, string credentialName, string fieldName)
{
if (string.IsNullOrEmpty(encryptedValue))
return string.Empty;
try
{
return _encryptionService.Decrypt(encryptedValue);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Impossibile decrittografare"))
{
_logger.LogWarning("Impossibile decrittografare {FieldName} per la credenziale {CredentialName}. Probabile migrazione tra macchine diverse.",
fieldName, credentialName);
return "*** CREDENZIALI NON DISPONIBILI - REINSERIRE ***";
}
catch (Exception ex)
{
_logger.LogWarning("Problema nella decrittografia di {FieldName} per la credenziale {CredentialName}: {Message}",
fieldName, credentialName, ex.Message);
return "*** ERRORE DECRITTOGRAFIA ***";
}
}
///
/// Verifica se una credenziale ha bisogno di essere re-inserita
///
/// Valore della credenziale
/// True se la credenziale deve essere re-inserita
private bool NeedsReentry(string credentialValue)
{
return credentialValue.Contains("*** CREDENZIALI NON DISPONIBILI") ||
credentialValue.Contains("*** ERRORE DECRITTOGRAFIA ***");
}
#endregion
}