using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Security.Cryptography; using watcher_monitoring.Data; using watcher_monitoring.Models; namespace watcher_monitoring.Controllers; [ApiController] [Route("[controller]")] public class ApiKeyController : Controller { private readonly WatcherDbContext _context; private readonly ILogger _logger; public ApiKeyController(WatcherDbContext context, ILogger logger) { _context = context; _logger = logger; } // Generiert einen neuen API-Key private static string GenerateApiKey() { var randomBytes = new byte[32]; using var rng = RandomNumberGenerator.Create(); rng.GetBytes(randomBytes); return Convert.ToBase64String(randomBytes).Replace("+", "").Replace("/", "").Replace("=", ""); } [HttpPost("create")] public async Task CreateApiKey([FromBody] CreateApiKeyRequest request) { if (string.IsNullOrWhiteSpace(request.Name)) { return BadRequest(new { error = "Name ist erforderlich" }); } var apiKey = new ApiKey { Key = GenerateApiKey(), Name = request.Name, Description = request.Description, ExpiresAt = request.ExpiresAt, IsActive = true }; _context.ApiKeys.Add(apiKey); await _context.SaveChangesAsync(); _logger.LogInformation("Neuer API-Key erstellt: {Name}", apiKey.Name); return Ok(new { id = apiKey.Id, key = apiKey.Key, // Wird nur einmal zurückgegeben! name = apiKey.Name, description = apiKey.Description, createdAt = apiKey.CreatedAt, expiresAt = apiKey.ExpiresAt, isActive = apiKey.IsActive }); } [HttpGet("list")] public async Task ListApiKeys() { var apiKeys = await _context.ApiKeys .OrderByDescending(k => k.CreatedAt) .Select(k => new { id = k.Id, name = k.Name, description = k.Description, createdAt = k.CreatedAt, expiresAt = k.ExpiresAt, lastUsedAt = k.LastUsedAt, isActive = k.IsActive, isExpired = k.IsExpired, keyPreview = k.Key.Substring(0, Math.Min(8, k.Key.Length)) + "..." // Nur die ersten 8 Zeichen }) .ToListAsync(); return Ok(apiKeys); } [HttpGet("{id}")] public async Task GetApiKey(int id) { var apiKey = await _context.ApiKeys.FindAsync(id); if (apiKey == null) { return NotFound(new { error = "API-Key nicht gefunden" }); } return Ok(new { id = apiKey.Id, name = apiKey.Name, description = apiKey.Description, createdAt = apiKey.CreatedAt, expiresAt = apiKey.ExpiresAt, lastUsedAt = apiKey.LastUsedAt, isActive = apiKey.IsActive, isExpired = apiKey.IsExpired, keyPreview = apiKey.Key.Substring(0, Math.Min(8, apiKey.Key.Length)) + "..." }); } [HttpPut("{id}/toggle")] public async Task ToggleApiKey(int id) { var apiKey = await _context.ApiKeys.FindAsync(id); if (apiKey == null) { return NotFound(new { error = "API-Key nicht gefunden" }); } apiKey.IsActive = !apiKey.IsActive; await _context.SaveChangesAsync(); _logger.LogInformation("API-Key {Name} wurde {Status}", apiKey.Name, apiKey.IsActive ? "aktiviert" : "deaktiviert"); return Ok(new { isActive = apiKey.IsActive }); } [HttpDelete("{id}")] public async Task DeleteApiKey(int id) { var apiKey = await _context.ApiKeys.FindAsync(id); if (apiKey == null) { return NotFound(new { error = "API-Key nicht gefunden" }); } _context.ApiKeys.Remove(apiKey); await _context.SaveChangesAsync(); _logger.LogInformation("API-Key gelöscht: {Name}", apiKey.Name); return Ok(new { message = "API-Key erfolgreich gelöscht" }); } } public class CreateApiKeyRequest { public string Name { get; set; } = string.Empty; public string? Description { get; set; } public DateTime? ExpiresAt { get; set; } }