Files
Watcher/watcher-monitoring/Controllers/ApiKeyController.cs
triggermeelmo d8b164e3eb
All checks were successful
Gitea CI/CD / dotnet-build-and-test (push) Successful in 10m5s
Gitea CI/CD / Set Tag Name (push) Successful in 5s
Gitea CI/CD / docker-build-and-push (push) Successful in 11m28s
Gitea CI/CD / Create Tag (push) Successful in 5s
Added Authentication with user-auth and apikey-auth
2026-01-09 10:18:06 +01:00

154 lines
4.5 KiB
C#

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<ApiKeyController> _logger;
public ApiKeyController(WatcherDbContext context, ILogger<ApiKeyController> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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; }
}