Files
flatrender/services/identity/FlatRender.IdentitySvc/Controllers/TenantsController.cs
T

126 lines
5.4 KiB
C#
Raw Normal View History

using FlatRender.IdentitySvc.Application.Services.Interfaces;
using FlatRender.IdentitySvc.Models.Requests;
using FlatRender.IdentitySvc.Models.Responses;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace FlatRender.IdentitySvc.Controllers;
[ApiController]
[Route("v1/tenants")]
[Authorize]
public class TenantsController(ITenantService tenantService) : ControllerBase
{
[HttpGet]
[ProducesResponseType(typeof(PagedResponse<TenantResponse>), 200)]
public async Task<IActionResult> List([FromQuery] int page = 1, [FromQuery] int pageSize = 20)
=> Ok(await tenantService.ListAsync(page, pageSize));
[HttpPost]
[ProducesResponseType(typeof(TenantResponse), 201)]
public async Task<IActionResult> Create([FromBody] CreateTenantRequest request)
{
var result = await tenantService.CreateAsync(request);
return StatusCode(201, result);
}
[HttpGet("by-slug/{slug}")]
[AllowAnonymous]
[ProducesResponseType(typeof(TenantResponse), 200)]
public async Task<IActionResult> GetBySlug(string slug)
=> Ok(await tenantService.GetBySlugAsync(slug));
[HttpGet("{tenantId:guid}")]
[ProducesResponseType(typeof(TenantResponse), 200)]
public async Task<IActionResult> GetById(Guid tenantId)
=> Ok(await tenantService.GetByIdAsync(tenantId));
[HttpPatch("{tenantId:guid}")]
[ProducesResponseType(typeof(TenantResponse), 200)]
public async Task<IActionResult> Update(Guid tenantId, [FromBody] UpdateTenantRequest request)
=> Ok(await tenantService.UpdateAsync(tenantId, request));
[HttpGet("{tenantId:guid}/branding")]
[ProducesResponseType(typeof(TenantBrandingResponse), 200)]
public async Task<IActionResult> GetBranding(Guid tenantId)
=> Ok(await tenantService.GetBrandingAsync(tenantId));
[HttpPut("{tenantId:guid}/branding")]
[ProducesResponseType(typeof(TenantBrandingResponse), 200)]
public async Task<IActionResult> UpsertBranding(Guid tenantId, [FromBody] TenantBrandingRequest request)
=> Ok(await tenantService.UpsertBrandingAsync(tenantId, request));
[HttpPost("{tenantId:guid}/domains/verify")]
[ProducesResponseType(typeof(DomainVerificationResponse), 200)]
public async Task<IActionResult> VerifyDomain(Guid tenantId, [FromBody] StartDomainVerificationRequest request)
=> Ok(await tenantService.StartDomainVerificationAsync(tenantId, request.Domain, request.Method));
[HttpGet("{tenantId:guid}/usage")]
[ProducesResponseType(typeof(object), 200)]
public async Task<IActionResult> GetUsage(
Guid tenantId,
[FromQuery] DateOnly from,
[FromQuery] DateOnly to)
{
var data = await tenantService.GetUsageAsync(tenantId, from, to);
return Ok(new { data });
}
// ── API Keys ──────────────────────────────────────────────────────────
[HttpGet("{tenantId:guid}/api-keys")]
public async Task<IActionResult> GetApiKeys(Guid tenantId)
=> Ok(new { data = await tenantService.GetApiKeysAsync(tenantId) });
[HttpPost("{tenantId:guid}/api-keys")]
public async Task<IActionResult> CreateApiKey(Guid tenantId, [FromBody] CreateApiKeyRequest request)
{
var userId = GetUserId();
var result = await tenantService.CreateApiKeyAsync(tenantId, userId, request);
return StatusCode(201, result);
}
[HttpDelete("{tenantId:guid}/api-keys/{apiKeyId:guid}")]
public async Task<IActionResult> RevokeApiKey(Guid tenantId, Guid apiKeyId, [FromBody] RevokeApiKeyRequest? request)
{
await tenantService.RevokeApiKeyAsync(tenantId, apiKeyId, request?.Reason);
return NoContent();
}
// ── Webhooks ──────────────────────────────────────────────────────────
[HttpGet("{tenantId:guid}/webhooks")]
public async Task<IActionResult> GetWebhooks(Guid tenantId)
=> Ok(new { data = await tenantService.GetWebhooksAsync(tenantId) });
[HttpPost("{tenantId:guid}/webhooks")]
public async Task<IActionResult> CreateWebhook(Guid tenantId, [FromBody] CreateWebhookRequest request)
{
var result = await tenantService.CreateWebhookAsync(tenantId, request);
return StatusCode(201, result);
}
[HttpDelete("{tenantId:guid}/webhooks/{webhookId:guid}")]
public async Task<IActionResult> DeleteWebhook(Guid tenantId, Guid webhookId)
{
await tenantService.DeleteWebhookAsync(tenantId, webhookId);
return NoContent();
}
[HttpGet("{tenantId:guid}/webhooks/{webhookId:guid}/deliveries")]
public async Task<IActionResult> GetWebhookDeliveries(Guid tenantId, Guid webhookId)
=> Ok(new { data = await tenantService.GetWebhookDeliveriesAsync(tenantId, webhookId) });
private Guid GetUserId() => Guid.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value
?? User.FindFirst("sub")?.Value ?? throw new UnauthorizedAccessException());
}
[ApiController]
[Route("v1/api-keys")]
public class ApiKeyValidationController(ITenantService tenantService) : ControllerBase
{
[HttpPost("validate")]
public async Task<IActionResult> Validate([FromBody] ValidateApiKeyRequest request)
=> Ok(await tenantService.ValidateApiKeyAsync(request.KeyPrefix, request.KeyHash, request.IpAddress));
}