using AmtScanner.Api.Data; using AmtScanner.Api.Models; using Microsoft.EntityFrameworkCore; using System.Text; namespace AmtScanner.Api.Services; public class CredentialService : ICredentialService { private readonly AppDbContext _context; private readonly ILogger _logger; public CredentialService(AppDbContext context, ILogger logger) { _context = context; _logger = logger; } public async Task> GetAllCredentialsAsync() { return await _context.AmtCredentials.ToListAsync(); } public async Task GetDefaultCredentialAsync() { var credential = await _context.AmtCredentials .FirstOrDefaultAsync(c => c.IsDefault); if (credential != null) { _logger.LogInformation("Found default credential: ID={Id}, name='{Name}', username='{Username}'", credential.Id, credential.Name, credential.Username); } else { _logger.LogWarning("No default credential found in database!"); } return credential; } public async Task CreateCredentialAsync(AmtCredential credential) { // If setting as default, unset other defaults if (credential.IsDefault) { var existing = await _context.AmtCredentials .Where(c => c.IsDefault) .ToListAsync(); foreach (var c in existing) { c.IsDefault = false; } } credential.Password = EncryptPassword(credential.Password); credential.CreatedAt = DateTime.UtcNow; credential.UpdatedAt = DateTime.UtcNow; _context.AmtCredentials.Add(credential); await _context.SaveChangesAsync(); _logger.LogInformation("Created AMT credential: {Name}", credential.Name); return credential; } public async Task UpdateCredentialAsync(long id, AmtCredential credential) { var existing = await _context.AmtCredentials.FindAsync(id); if (existing == null) { throw new KeyNotFoundException($"Credential with ID {id} not found"); } // If setting as default, unset other defaults if (credential.IsDefault && !existing.IsDefault) { var others = await _context.AmtCredentials .Where(c => c.IsDefault && c.Id != id) .ToListAsync(); foreach (var c in others) { c.IsDefault = false; } } existing.Name = credential.Name; existing.Username = credential.Username; if (!string.IsNullOrEmpty(credential.Password)) { existing.Password = EncryptPassword(credential.Password); } existing.IsDefault = credential.IsDefault; existing.Description = credential.Description; existing.UpdatedAt = DateTime.UtcNow; await _context.SaveChangesAsync(); _logger.LogInformation("Updated AMT credential: {Name}", existing.Name); return existing; } public async Task DeleteCredentialAsync(long id) { var credential = await _context.AmtCredentials.FindAsync(id); if (credential != null) { _context.AmtCredentials.Remove(credential); await _context.SaveChangesAsync(); _logger.LogInformation("Deleted AMT credential: {Id}", id); } } public string EncryptPassword(string password) { // Simple Base64 encoding (production should use proper encryption) return Convert.ToBase64String(Encoding.UTF8.GetBytes(password)); } public string DecryptPassword(string encryptedPassword) { try { return Encoding.UTF8.GetString(Convert.FromBase64String(encryptedPassword)); } catch (Exception ex) { _logger.LogError(ex, "Failed to decrypt password"); return string.Empty; } } }