mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 08:36:11 +02:00
110 lines
3.4 KiB
C#
110 lines
3.4 KiB
C#
using System.Reflection;
|
|
using System.Security.Claims;
|
|
using EchoHub.Core.DTOs;
|
|
using EchoHub.Core.Models;
|
|
using EchoHub.Server.Data;
|
|
using EchoHub.Server.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace EchoHub.Server.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/server")]
|
|
public class ServerController : ControllerBase
|
|
{
|
|
private readonly EchoHubDbContext _db;
|
|
private readonly IConfiguration _config;
|
|
private readonly DirectoryClaimStore _claimStore;
|
|
|
|
public ServerController(EchoHubDbContext db, IConfiguration config, DirectoryClaimStore claimStore)
|
|
{
|
|
_db = db;
|
|
_config = config;
|
|
_claimStore = claimStore;
|
|
}
|
|
|
|
[HttpGet("info")]
|
|
public async Task<IActionResult> GetInfo()
|
|
{
|
|
var userCount = await _db.Users.CountAsync();
|
|
var channelCount = await _db.Channels.CountAsync();
|
|
|
|
var registrationMode = (_config["Server:Registration"] ?? "open").Trim().ToLowerInvariant() switch
|
|
{
|
|
"invite" => "invite",
|
|
"closed" => "closed",
|
|
_ => "open",
|
|
};
|
|
|
|
var version = typeof(ServerController).Assembly.GetName().Version?.ToString(3) ?? "0.0.0";
|
|
|
|
var status = new ServerStatusDto(
|
|
_config["Server:Name"] ?? "EchoHub Server",
|
|
_config["Server:Description"],
|
|
userCount,
|
|
channelCount,
|
|
registrationMode,
|
|
version);
|
|
|
|
return Ok(status);
|
|
}
|
|
|
|
[HttpGet("encryption-key")]
|
|
[Authorize]
|
|
[EnableRateLimiting("auth")]
|
|
public IActionResult GetEncryptionKey()
|
|
{
|
|
var key = _config["Encryption:Key"];
|
|
|
|
if (string.IsNullOrEmpty(key))
|
|
return StatusCode(503, new ErrorResponse("Encryption is not configured on this server."));
|
|
|
|
return Ok(new EncryptionKeyResponse(key));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Operator-facing view of the EchoHubSpace directory registration: ServerId for admin
|
|
/// support tickets, current registration state, and the last error/conflict if any.
|
|
/// Never exposes the claim token itself.
|
|
/// </summary>
|
|
[HttpGet("directory")]
|
|
[Authorize]
|
|
public async Task<IActionResult> GetDirectoryStatus()
|
|
{
|
|
var (_, error) = await GetCallerAsync(ServerRole.Admin);
|
|
if (error is not null) return error;
|
|
|
|
var status = _claimStore.Status;
|
|
var response = new
|
|
{
|
|
ServerId = _claimStore.ServerId,
|
|
HasClaimToken = _claimStore.ClaimToken is not null,
|
|
status.IsRegistered,
|
|
status.LastRegisteredAt,
|
|
status.LastError,
|
|
status.ConflictingHosts,
|
|
};
|
|
|
|
return Ok(response);
|
|
}
|
|
|
|
private async Task<(User? Caller, IActionResult? Error)> GetCallerAsync(ServerRole minimumRole)
|
|
{
|
|
var userIdClaim = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
if (userIdClaim is null)
|
|
return (null, Unauthorized(new ErrorResponse("Authentication required.")));
|
|
|
|
var caller = await _db.Users.FindAsync(Guid.Parse(userIdClaim));
|
|
if (caller is null)
|
|
return (null, Unauthorized(new ErrorResponse("User not found.")));
|
|
|
|
if (caller.Role < minimumRole)
|
|
return (null, StatusCode(403, new ErrorResponse($"Requires {minimumRole} role or higher.")));
|
|
|
|
return (caller, null);
|
|
}
|
|
}
|