115 lines
3.8 KiB
C#
115 lines
3.8 KiB
C#
using Management.Data;
|
|
using Management.Security;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Text.Json;
|
|
|
|
namespace Management.Controllers;
|
|
|
|
/// <summary>
|
|
/// Onboarding endpoints for new user/client registration.
|
|
/// Requires JWT authentication (user may not have session yet).
|
|
///
|
|
/// ENDPOINTS:
|
|
/// GET /api/onboarding/status - Check registration status
|
|
/// POST /api/onboarding/register - Register new organization
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/onboarding")]
|
|
public sealed class OnboardingController : ControllerBase
|
|
{
|
|
private readonly SqlService _sql;
|
|
private readonly ClientContext _client;
|
|
private readonly ILogger<OnboardingController> _log;
|
|
|
|
public OnboardingController(SqlService sql, ClientContext client, ILogger<OnboardingController> log)
|
|
{
|
|
_sql = sql;
|
|
_client = client;
|
|
_log = log;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check registration status for authenticated user.
|
|
/// </summary>
|
|
[HttpGet("status")]
|
|
public async Task<IActionResult> Status(CancellationToken ct)
|
|
{
|
|
if (!_client.IsAuthenticated)
|
|
return Unauthorized(new { ok = false, error = "Valid Entra authentication required" });
|
|
|
|
var rqst = JsonSerializer.Serialize(new
|
|
{
|
|
provider = "EntraExternalId",
|
|
subject = _client.ClientId,
|
|
email = _client.Email
|
|
});
|
|
|
|
try
|
|
{
|
|
var resp = await _sql.ExecProcAsync("dbo.spOnboarding", "status", rqst, ct: ct);
|
|
|
|
if (string.IsNullOrWhiteSpace(resp))
|
|
return StatusCode(500, new { ok = false, error = "Service unavailable" });
|
|
|
|
return Content(resp, "application/json");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.LogError(ex, "[Onboarding] Status error");
|
|
return StatusCode(500, new { ok = false, error = "Status check failed", detail = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register a new organization.
|
|
/// </summary>
|
|
[HttpPost("register")]
|
|
public async Task<IActionResult> Register([FromBody] RegisterRequest request, CancellationToken ct)
|
|
{
|
|
if (!_client.IsAuthenticated)
|
|
return Unauthorized(new { ok = false, error = "Valid Entra authentication required" });
|
|
|
|
if (string.IsNullOrWhiteSpace(request?.ClientName))
|
|
return BadRequest(new { ok = false, error = "clientName is required" });
|
|
|
|
_log.LogWarning("[Onboarding] Register | Subject={Subject} ClientName={ClientName}",
|
|
_client.ClientId, request.ClientName);
|
|
|
|
var rqst = JsonSerializer.Serialize(new
|
|
{
|
|
provider = "EntraExternalId",
|
|
subject = _client.ClientId,
|
|
email = _client.Email,
|
|
displayName = _client.ClientName,
|
|
clientName = request.ClientName.Trim()
|
|
});
|
|
|
|
try
|
|
{
|
|
var resp = await _sql.ExecProcAsync("dbo.spOnboarding", "register", rqst, ct: ct);
|
|
|
|
if (string.IsNullOrWhiteSpace(resp))
|
|
return StatusCode(500, new { ok = false, error = "Registration service unavailable" });
|
|
|
|
using var doc = JsonDocument.Parse(resp);
|
|
var root = doc.RootElement;
|
|
|
|
if (root.TryGetProperty("ok", out var okProp) && okProp.GetBoolean())
|
|
return Content(resp, "application/json");
|
|
|
|
var error = root.TryGetProperty("error", out var errProp) ? errProp.GetString() : "Registration failed";
|
|
return BadRequest(new { ok = false, error });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.LogError(ex, "[Onboarding] Register error");
|
|
return StatusCode(500, new { ok = false, error = "Registration failed", detail = ex.Message });
|
|
}
|
|
}
|
|
}
|
|
|
|
public sealed class RegisterRequest
|
|
{
|
|
public string? ClientName { get; set; }
|
|
}
|