diff --git a/BlazorApp/Endpoints/DeveloperEndpoints.cs b/BlazorApp/Endpoints/DeveloperEndpoints.cs index 1b372e5..1a763f0 100644 --- a/BlazorApp/Endpoints/DeveloperEndpoints.cs +++ b/BlazorApp/Endpoints/DeveloperEndpoints.cs @@ -17,10 +17,10 @@ public static class DeveloperEndpoints : Results.Problem(message, statusCode: 502); }); - group.MapPost("/approve/{ticketId:int}", async ( - int ticketId, - ApproveRequest request, - ProvisioningService service, + group.MapPost("/approve/{ticketId}", async ( + string ticketId, + DeveloperTicketParsingService ticketService, + ProvisioningService provisioningService, HttpContext context, IConfiguration config) => { @@ -30,8 +30,18 @@ public static class DeveloperEndpoints if (string.IsNullOrEmpty(expectedKey) || apiKey != expectedKey) return Results.Unauthorized(); - var (success, message) = await service.ApproveApplicationAsync( - ticketId, request.Username, request.Email, request.FullName); + var ticket = await ticketService.FetchTicketAsync(ticketId); + if (ticket is null) + return Results.Problem("Failed to fetch ticket from SilverDESK", statusCode: 502); + + var description = ticket.Value.GetProperty("description").GetString() ?? ""; + var (fullName, email, desiredUsername) = ticketService.ParseApplicationFromDescription(description); + + if (string.IsNullOrEmpty(fullName) || string.IsNullOrEmpty(email) || string.IsNullOrEmpty(desiredUsername)) + return Results.Problem("Could not parse applicant details from ticket description", statusCode: 422); + + var (success, message) = await provisioningService.ApproveApplicationAsync( + ticketId, desiredUsername, email, fullName); return success ? Results.Ok(new { message }) @@ -39,5 +49,3 @@ public static class DeveloperEndpoints }); } } - -public record ApproveRequest(string Username, string Email, string FullName); diff --git a/BlazorApp/Program.cs b/BlazorApp/Program.cs index c07b65b..169a4b5 100644 --- a/BlazorApp/Program.cs +++ b/BlazorApp/Program.cs @@ -17,6 +17,15 @@ builder.Services.AddHttpClient(client => client.DefaultRequestHeaders.Add("X-API-Key", apiKey); }); +// HttpClient for DeveloperTicketParsingService (fetches tickets from SilverDESK) +builder.Services.AddHttpClient(client => +{ + client.BaseAddress = new Uri(builder.Configuration["SilverDesk:BaseUrl"] ?? "https://silverdesk.silverlabs.uk"); + var apiKey = builder.Configuration["SilverDesk:ApiKey"]; + if (!string.IsNullOrEmpty(apiKey)) + client.DefaultRequestHeaders.Add("X-API-Key", apiKey); +}); + // Named HttpClients for provisioning builder.Services.AddHttpClient("SilverDesk", client => { diff --git a/BlazorApp/Services/DeveloperTicketParsingService.cs b/BlazorApp/Services/DeveloperTicketParsingService.cs new file mode 100644 index 0000000..d819cb2 --- /dev/null +++ b/BlazorApp/Services/DeveloperTicketParsingService.cs @@ -0,0 +1,52 @@ +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace SilverLabs.Website.Services; + +public class DeveloperTicketParsingService +{ + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + + public DeveloperTicketParsingService(HttpClient httpClient, ILogger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + public async Task FetchTicketAsync(string ticketId) + { + try + { + var response = await _httpClient.GetAsync($"/api/tickets/{ticketId}"); + if (!response.IsSuccessStatusCode) + { + _logger.LogError("Failed to fetch ticket {TicketId}: {Status}", ticketId, response.StatusCode); + return null; + } + + var json = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(json); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching ticket {TicketId}", ticketId); + return null; + } + } + + public (string? FullName, string? Email, string? DesiredUsername) ParseApplicationFromDescription(string description) + { + var fullName = ExtractField(description, @"\*\*Full Name:\*\*\s*(.+)"); + var email = ExtractField(description, @"\*\*Email:\*\*\s*(.+)"); + var desiredUsername = ExtractField(description, @"\*\*Desired Username:\*\*\s*(.+)"); + + return (fullName, email, desiredUsername); + } + + private static string? ExtractField(string text, string pattern) + { + var match = Regex.Match(text, pattern); + return match.Success ? match.Groups[1].Value.Trim() : null; + } +} diff --git a/BlazorApp/Services/ProvisioningService.cs b/BlazorApp/Services/ProvisioningService.cs index d6d8c03..2d240e8 100644 --- a/BlazorApp/Services/ProvisioningService.cs +++ b/BlazorApp/Services/ProvisioningService.cs @@ -15,7 +15,7 @@ public class ProvisioningService } public async Task<(bool Success, string Message)> ApproveApplicationAsync( - int ticketId, string username, string email, string fullName) + string ticketId, string username, string email, string fullName) { var results = new List(); var allSuccess = true; @@ -35,14 +35,8 @@ public class ProvisioningService results.Add($"Mailcow: {mailMsg}"); if (!mailOk) allSuccess = false; - // 4. Update SilverDESK ticket - if (allSuccess) - { - await UpdateTicketStatusAsync(ticketId, "approved", string.Join("\n", results)); - } - var summary = string.Join("; ", results); - _logger.LogInformation("Provisioning for {Username}: {Summary}", username, summary); + _logger.LogInformation("Provisioning for {Username} (ticket {TicketId}): {Summary}", username, ticketId, summary); return (allSuccess, summary); } @@ -136,21 +130,4 @@ public class ProvisioningService return (false, $"Error: {ex.Message}"); } } - - private async Task UpdateTicketStatusAsync(int ticketId, string status, string note) - { - try - { - var client = _httpClientFactory.CreateClient("SilverDesk"); - var payload = new { status, note = $"Application approved. Provisioning results:\n{note}" }; - var json = JsonSerializer.Serialize(payload); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - - await client.PutAsync($"/api/tickets/{ticketId}", content); - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to update ticket {TicketId} status", ticketId); - } - } } diff --git a/BlazorApp/appsettings.json b/BlazorApp/appsettings.json index 558f331..18b5930 100644 --- a/BlazorApp/appsettings.json +++ b/BlazorApp/appsettings.json @@ -18,5 +18,5 @@ "BaseUrl": "https://mail.silverlined.uk", "ApiKey": "" }, - "AdminApiKey": "" + "AdminApiKey": "aawb2MHblbfmqdhcS7Xp2/ibQOUbUE1BDoqdJOu0bjM=" }