using System.Text; using Microsoft.AspNetCore.Authentication; using SharepointToolbox.Web.Core.Models; using SharepointToolbox.Web.Infrastructure.Persistence; using SharepointToolbox.Web.Services.Session; namespace SharepointToolbox.Web.Services.Audit; public class AuditService : IAuditService { private readonly AuditRepository _repo; private readonly IUserContextAccessor _userContext; public AuditService(AuditRepository repo, IUserContextAccessor userContext) { _repo = repo; _userContext = userContext; } public async Task LogAsync(string action, string clientName, IEnumerable sites, string details = "") { var entry = new AuditEntry { Action = action, ClientName = clientName, Sites = sites.ToList(), Details = details, UserEmail = _userContext.Email, UserDisplay = _userContext.DisplayName, UserRole = _userContext.Role }; await _repo.AppendAsync(entry); } public Task> GetAllAsync() => _repo.LoadAllAsync(); public async Task ExportCsvAsync() { var entries = await _repo.LoadAllAsync(); var sb = new StringBuilder(); sb.AppendLine("Timestamp,UserEmail,UserDisplay,UserRole,Action,Client,Sites,Details"); foreach (var e in entries.OrderByDescending(x => x.Timestamp)) { sb.AppendLine(string.Join(",", CsvEscape(e.Timestamp.ToString("yyyy-MM-dd HH:mm:ss")), CsvEscape(e.UserEmail), CsvEscape(e.UserDisplay), CsvEscape(e.UserRole.ToString()), CsvEscape(e.Action), CsvEscape(e.ClientName), CsvEscape(string.Join("; ", e.Sites)), CsvEscape(e.Details))); } return sb.ToString(); } private static string CsvEscape(string value) { if (value.Contains(',') || value.Contains('"') || value.Contains('\n')) return $"\"{value.Replace("\"", "\"\"")}\""; return value; } }