using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Application.Backoffice; using Tiku.Application.Security; namespace Tiku.Api.Controllers; [ApiController] [Route("api/backoffice")] public sealed class BackofficeController( IBackofficeService backofficeService, ICurrentUser currentUser, ITenantContext tenantContext) : ControllerBase { [HttpGet("tenant/bootstrap")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetTenantBootstrap(CancellationToken cancellationToken) { return Ok(await backofficeService.GetTenantBootstrapAsync(ResolveTenantActor(), cancellationToken)); } [HttpPost("tenant/roles")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> UpsertTenantRole( UpsertBackofficeRoleDto request, CancellationToken cancellationToken) { return Ok(await backofficeService.UpsertTenantRoleAsync(ResolveTenantActor(), request.ToCommand(), cancellationToken)); } [HttpPut("tenant/roles/{roleId:guid}/bindings")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> ReplaceTenantRoleBindings( Guid roleId, ReplaceRoleBindingsDto request, CancellationToken cancellationToken) { return Ok(await backofficeService.ReplaceTenantRoleBindingsAsync(ResolveTenantActor(), request.ToCommand(roleId), cancellationToken)); } [HttpPut("tenant/users/{userId:guid}/roles")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task ReplaceTenantUserRoles( Guid userId, ReplaceUserRolesDto request, CancellationToken cancellationToken) { await backofficeService.ReplaceTenantUserRolesAsync(ResolveTenantActor(), request.ToCommand(userId), cancellationToken); return NoContent(); } [HttpGet("platform/bootstrap")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetPlatformBootstrap(CancellationToken cancellationToken) { return Ok(await backofficeService.GetPlatformBootstrapAsync(ResolvePlatformActor(), cancellationToken)); } [HttpPost("platform/roles")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> UpsertPlatformRole( UpsertBackofficeRoleDto request, CancellationToken cancellationToken) { return Ok(await backofficeService.UpsertPlatformRoleAsync(ResolvePlatformActor(), request.ToCommand(), cancellationToken)); } [HttpPut("platform/roles/{roleId:guid}/bindings")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> ReplacePlatformRoleBindings( Guid roleId, ReplaceRoleBindingsDto request, CancellationToken cancellationToken) { return Ok(await backofficeService.ReplacePlatformRoleBindingsAsync(ResolvePlatformActor(), request.ToCommand(roleId), cancellationToken)); } [HttpPut("platform/users/{userId:guid}/roles")] [Authorize(Policy = TikuPolicies.TenantAdmin)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task ReplacePlatformUserRoles( Guid userId, ReplaceUserRolesDto request, CancellationToken cancellationToken) { await backofficeService.ReplacePlatformUserRolesAsync(ResolvePlatformActor(), request.ToCommand(userId), cancellationToken); return NoContent(); } private BackofficeActor ResolveTenantActor() { if (currentUser.UserId is not { } userId || tenantContext.TenantId is not { } tenantId) { throw new InvalidOperationException("Tenant backoffice actor was not resolved."); } return new BackofficeActor(userId, tenantId, IsPlatformAdmin()); } private BackofficeActor ResolvePlatformActor() { if (currentUser.UserId is not { } userId) { throw new InvalidOperationException("Platform backoffice actor was not resolved."); } return new BackofficeActor(userId, tenantContext.TenantId, IsPlatformAdmin()); } private bool IsPlatformAdmin() { return string.Equals(currentUser.TenantRole, "PlatformAdmin", StringComparison.OrdinalIgnoreCase); } }