Refactoring gestione sessione e persistenza impostazioni
Introdotto `SessionService` per centralizzare la gestione della sessione utente, migliorando la separazione delle responsabilità e la testabilità. Risolto il problema del caricamento del cookie di autenticazione all'avvio e garantita la persistenza delle checkbox di esportazione (`IncludeMetadata`, `RemoveAfterExport`, `OverwriteExisting`). Ottimizzata la gestione della barra degli indirizzi del browser con aggiornamenti locali immediati. Applicato il pattern "Load ? Modify ? Save" per il salvataggio delle impostazioni, migliorando la simmetria e la leggibilità del codice. Logging centralizzato e semplificato per eventi rilevanti. Aggiornata la documentazione per riflettere i cambiamenti e verificati i test per garantire il corretto funzionamento.
This commit is contained in:
@@ -88,7 +88,8 @@ namespace AutoBidder.Services
|
||||
if (!_auctions.Any(a => a.AuctionId == auction.AuctionId))
|
||||
{
|
||||
_auctions.Add(auction);
|
||||
OnLog?.Invoke($"[+] Asta aggiunta: {auction.Name} (ID: {auction.AuctionId})");
|
||||
// ? RIMOSSO: Log ridondante - viene già loggato da MainWindow con defaults e stato
|
||||
// OnLog?.Invoke($"[+] Asta aggiunta: {auction.Name} (ID: {auction.AuctionId})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +102,8 @@ namespace AutoBidder.Services
|
||||
if (auction != null)
|
||||
{
|
||||
_auctions.Remove(auction);
|
||||
OnLog?.Invoke($"[-] Asta rimossa: {auction.Name}");
|
||||
// ? RIMOSSO: Log ridondante - viene già loggato da MainWindow con più dettagli
|
||||
// OnLog?.Invoke($"[-] Asta rimossa: {auction.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -552,5 +554,13 @@ namespace AutoBidder.Services
|
||||
{
|
||||
return await _apiClient.PlaceBidAsync(auction.AuctionId, auction.OriginalUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Espone ApiClient per SessionService
|
||||
/// </summary>
|
||||
public BidooApiClient GetApiClient()
|
||||
{
|
||||
return _apiClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using AutoBidder.Models;
|
||||
|
||||
namespace AutoBidder.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Servizio centralizzato per gestione sessione utente
|
||||
/// Responsabile di: Load, Save, Validate, Activate
|
||||
///
|
||||
/// PATTERN: Single Responsibility + Dependency Injection
|
||||
/// </summary>
|
||||
public class SessionService
|
||||
{
|
||||
private readonly BidooApiClient _apiClient;
|
||||
private BidooSession? _currentSession;
|
||||
|
||||
public event Action<string>? OnLog;
|
||||
public event Action<BidooSession>? OnSessionChanged;
|
||||
|
||||
public SessionService(BidooApiClient apiClient)
|
||||
{
|
||||
_apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Carica sessione salvata da disco (se esiste)
|
||||
/// </summary>
|
||||
public BidooSession? LoadSession()
|
||||
{
|
||||
try
|
||||
{
|
||||
var session = SessionManager.LoadSession();
|
||||
|
||||
if (session != null && session.IsValid)
|
||||
{
|
||||
_currentSession = session;
|
||||
return session;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnLog?.Invoke($"[SESSION ERROR] Caricamento fallito: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva sessione su disco (crittografata con DPAPI)
|
||||
/// </summary>
|
||||
public bool SaveSession(BidooSession session)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (session == null || !session.IsValid)
|
||||
{
|
||||
OnLog?.Invoke("[SESSION ERROR] Sessione non valida, impossibile salvare");
|
||||
return false;
|
||||
}
|
||||
|
||||
var success = SessionManager.SaveSession(session);
|
||||
|
||||
if (success)
|
||||
{
|
||||
_currentSession = session;
|
||||
OnLog?.Invoke($"[SESSION] Salvata sessione per: {session.Username}");
|
||||
OnSessionChanged?.Invoke(session);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnLog?.Invoke("[SESSION ERROR] Salvataggio fallito");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnLog?.Invoke($"[SESSION ERROR] Salvataggio fallito: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Valida e attiva sessione: verifica che il cookie funzioni
|
||||
///
|
||||
/// QUESTO È IL METODO PRINCIPALE da usare:
|
||||
/// - All'avvio per validare sessione salvata
|
||||
/// - Dopo inserimento/modifica cookie
|
||||
///
|
||||
/// GARANTISCE l'ordine corretto delle chiamate:
|
||||
/// 1. Inizializza cookie nel client HTTP
|
||||
/// 2. Attiva sessione server-side (buy_bids.php)
|
||||
/// 3. Recupera e valida dati utente
|
||||
/// </summary>
|
||||
public async Task<SessionValidationResult> ValidateAndActivateSessionAsync(string cookieString, string? username = null)
|
||||
{
|
||||
var result = new SessionValidationResult();
|
||||
|
||||
try
|
||||
{
|
||||
// Step 1: Inizializza cookie nel client HTTP
|
||||
_apiClient.InitializeSessionWithCookie(cookieString, username ?? string.Empty);
|
||||
|
||||
// Step 2: CHIAVE - Attiva sessione server-side
|
||||
// Questo chiama buy_bids.php che:
|
||||
// - Crea stato sessione server
|
||||
// - Valida il cookie
|
||||
// - Restituisce dati utente
|
||||
var activationSuccess = await _apiClient.UpdateUserInfoAsync();
|
||||
|
||||
if (!activationSuccess)
|
||||
{
|
||||
result.Success = false;
|
||||
result.ErrorMessage = "Impossibile attivare sessione - cookie potrebbe essere scaduto o non valido";
|
||||
OnLog?.Invoke($"[SESSION ERROR] {result.ErrorMessage}");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Step 3: Recupera dati utente aggiornati
|
||||
var session = _apiClient.GetSession();
|
||||
|
||||
if (session == null || string.IsNullOrEmpty(session.Username))
|
||||
{
|
||||
result.Success = false;
|
||||
result.ErrorMessage = "Sessione attivata ma dati utente non disponibili";
|
||||
OnLog?.Invoke($"[SESSION ERROR] {result.ErrorMessage}");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Step 4: Successo!
|
||||
result.Success = true;
|
||||
result.Session = session;
|
||||
_currentSession = session;
|
||||
|
||||
OnLog?.Invoke($"[SESSION OK] Validata e attiva: {session.Username}, {session.RemainingBids} puntate");
|
||||
OnSessionChanged?.Invoke(session);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Success = false;
|
||||
result.ErrorMessage = $"Eccezione durante validazione: {ex.Message}";
|
||||
OnLog?.Invoke($"[SESSION EXCEPTION] {ex.Message}");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene sessione corrente in memoria
|
||||
/// </summary>
|
||||
public BidooSession? GetCurrentSession()
|
||||
{
|
||||
return _currentSession;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiorna dati utente (puntate residue, credito, ecc.)
|
||||
/// Da chiamare periodicamente o dopo ogni puntata
|
||||
/// </summary>
|
||||
public async Task<bool> RefreshUserInfoAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnLog?.Invoke("[SESSION] Refresh dati utente...");
|
||||
|
||||
var success = await _apiClient.UpdateUserInfoAsync();
|
||||
|
||||
if (success)
|
||||
{
|
||||
_currentSession = _apiClient.GetSession();
|
||||
|
||||
if (_currentSession != null)
|
||||
{
|
||||
OnLog?.Invoke($"[SESSION] Dati aggiornati: {_currentSession.Username}, {_currentSession.RemainingBids} puntate");
|
||||
OnSessionChanged?.Invoke(_currentSession);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnLog?.Invoke("[SESSION WARN] Refresh fallito");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnLog?.Invoke($"[SESSION ERROR] Refresh fallito: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulisce sessione corrente (memoria + disco)
|
||||
/// </summary>
|
||||
public void ClearSession()
|
||||
{
|
||||
_currentSession = null;
|
||||
SessionManager.ClearSession();
|
||||
OnLog?.Invoke("[SESSION] Sessione pulita");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Risultato della validazione sessione
|
||||
/// </summary>
|
||||
public class SessionValidationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// True se la validazione è riuscita
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sessione validata e attiva (null se validazione fallita)
|
||||
/// </summary>
|
||||
public BidooSession? Session { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Messaggio di errore (null se validazione riuscita)
|
||||
/// </summary>
|
||||
public string? ErrorMessage { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user