Files
Website/BlazorApp/Services/ProvisioningService.cs
SysAdmin ed5d14989a
All checks were successful
Build and Deploy / deploy (push) Successful in 16s
feat(developers): fix approval webhook flow and add ticket parsing service
Change approve endpoint from int to string ticketId to match SilverDESK
GUIDs. Remove body parameter requirement so the endpoint works as a
webhook target. Add DeveloperTicketParsingService to fetch and parse
applicant details from ticket descriptions. Remove redundant ticket
status update from ProvisioningService since SilverDESK action engine
now handles SetStatus/AddNote/AddReply steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:10:46 +00:00

134 lines
5.3 KiB
C#

using System.Text;
using System.Text.Json;
namespace SilverLabs.Website.Services;
public class ProvisioningService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<ProvisioningService> _logger;
public ProvisioningService(IHttpClientFactory httpClientFactory, ILogger<ProvisioningService> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
}
public async Task<(bool Success, string Message)> ApproveApplicationAsync(
string ticketId, string username, string email, string fullName)
{
var results = new List<string>();
var allSuccess = true;
// 1. Create SilverDESK user
var (deskOk, deskMsg) = await CreateSilverDeskUserAsync(username, email, fullName);
results.Add($"SilverDESK: {deskMsg}");
if (!deskOk) allSuccess = false;
// 2. Create Mattermost user
var (mmOk, mmMsg) = await CreateMattermostUserAsync(username, email, fullName);
results.Add($"Mattermost: {mmMsg}");
if (!mmOk) allSuccess = false;
// 3. Create Mailcow mailbox
var (mailOk, mailMsg) = await CreateMailcowMailboxAsync(username, fullName);
results.Add($"Mailcow: {mailMsg}");
if (!mailOk) allSuccess = false;
var summary = string.Join("; ", results);
_logger.LogInformation("Provisioning for {Username} (ticket {TicketId}): {Summary}", username, ticketId, summary);
return (allSuccess, summary);
}
public async Task<(bool Success, string Message)> CreateSilverDeskUserAsync(string username, string email, string fullName)
{
try
{
var client = _httpClientFactory.CreateClient("SilverDesk");
var payload = new { username, email, name = fullName, role = "user" };
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("/api/users", content);
if (response.IsSuccessStatusCode)
return (true, "User created");
var body = await response.Content.ReadAsStringAsync();
_logger.LogError("SilverDESK user creation failed: {Status} {Body}", response.StatusCode, body);
return (false, $"Failed ({response.StatusCode})");
}
catch (Exception ex)
{
_logger.LogError(ex, "SilverDESK user creation error for {Username}", username);
return (false, $"Error: {ex.Message}");
}
}
public async Task<(bool Success, string Message)> CreateMattermostUserAsync(string username, string email, string fullName)
{
try
{
var client = _httpClientFactory.CreateClient("Mattermost");
var nameParts = fullName.Split(' ', 2);
var payload = new
{
email,
username,
first_name = nameParts[0],
last_name = nameParts.Length > 1 ? nameParts[1] : "",
password = Guid.NewGuid().ToString("N")[..16] + "!A1" // Temporary password
};
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("/api/v4/users", content);
if (response.IsSuccessStatusCode)
return (true, "User created");
var body = await response.Content.ReadAsStringAsync();
_logger.LogError("Mattermost user creation failed: {Status} {Body}", response.StatusCode, body);
return (false, $"Failed ({response.StatusCode})");
}
catch (Exception ex)
{
_logger.LogError(ex, "Mattermost user creation error for {Username}", username);
return (false, $"Error: {ex.Message}");
}
}
public async Task<(bool Success, string Message)> CreateMailcowMailboxAsync(string username, string fullName)
{
try
{
var client = _httpClientFactory.CreateClient("Mailcow");
var payload = new
{
local_part = username,
domain = "silverlabs.uk",
name = fullName,
password = Guid.NewGuid().ToString("N")[..16] + "!A1", // Temporary password
password2 = "",
quota = 1024, // 1GB
active = 1,
force_pw_update = 1
};
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("/api/v1/add/mailbox", content);
if (response.IsSuccessStatusCode)
return (true, "Mailbox created");
var body = await response.Content.ReadAsStringAsync();
_logger.LogError("Mailcow mailbox creation failed: {Status} {Body}", response.StatusCode, body);
return (false, $"Failed ({response.StatusCode})");
}
catch (Exception ex)
{
_logger.LogError(ex, "Mailcow mailbox creation error for {Username}", username);
return (false, $"Error: {ex.Message}");
}
}
}