using System.Text; using Microsoft.Extensions.Options; using Newtonsoft.Json; namespace FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik; public class AuthentikClient : IAuthenticationServiceClient { private readonly HttpClient _httpClient; private readonly ILogger _logger; private readonly AuthentikConfiguration _configuration; public AuthentikClient( HttpClient httpClient, ILogger logger, IOptions configuration) { _httpClient = httpClient; _logger = logger; _configuration = configuration.Value; } public async Task CreateUserAsync(string username, string email, string displayName) { var request = new AuthentikAddUserRequest { Username = username, Email = email, DisplayName = displayName, IsActive = true }; try { var json = JsonConvert.SerializeObject(request); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await _httpClient.PostAsync("/api/v3/core/users/", content); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); _logger.LogError( "Failed to create user in Authentik. Status: {StatusCode}, Error: {Error}", response.StatusCode, errorContent); return null; } var responseJson = await response.Content.ReadAsStringAsync(); var userResponse = JsonConvert.DeserializeObject(responseJson); _logger.LogInformation("Successfully created user {Username} in Authentik with pk {Pk}", username, userResponse?.Pk); return userResponse; } catch (Exception ex) { _logger.LogError(ex, "Exception while creating user {Username} in Authentik", username); return null; } } public async Task SendRecoveryEmailAsync(int authentikUserId) { try { var response = await _httpClient.PostAsync( $"/api/v3/core/users/{authentikUserId}/recovery_email/?email_stage={_configuration.EmailStageId}", null); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); _logger.LogError( "Failed to send recovery email for user {UserId}. Status: {StatusCode}, Error: {Error}", authentikUserId, response.StatusCode, errorContent); return false; } _logger.LogInformation("Successfully sent recovery email to Authentik user {UserId}", authentikUserId); return true; } catch (Exception ex) { _logger.LogError(ex, "Exception while sending recovery email to Authentik user {UserId}", authentikUserId); return false; } } }