[FA-55] User Service backend initial setup
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik;
|
||||
|
||||
public class AuthentikAddUserRequest
|
||||
{
|
||||
[JsonPropertyName("username")]
|
||||
public required string Username { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public required string DisplayName { get; set; }
|
||||
|
||||
[JsonPropertyName("email")]
|
||||
public required string Email { get; set; }
|
||||
|
||||
[JsonPropertyName("is_active")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; } = "external";
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik;
|
||||
|
||||
public class AuthentikClient : IAuthenticationServiceClient
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ILogger<AuthentikClient> _logger;
|
||||
|
||||
public AuthentikClient(HttpClient httpClient, ILogger<AuthentikClient> logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<AuthentikUserResponse?> CreateUserAsync(string username, string email, string displayName)
|
||||
{
|
||||
var request = new AuthentikAddUserRequest
|
||||
{
|
||||
Username = username,
|
||||
Email = email,
|
||||
DisplayName = displayName,
|
||||
IsActive = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PostAsJsonAsync("/api/v3/core/users/", request);
|
||||
|
||||
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 userResponse = await response.Content.ReadFromJsonAsync<AuthentikUserResponse>();
|
||||
_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<bool> SendRecoveryEmailAsync(int authentikUserId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PostAsync(
|
||||
$"/api/v3/core/users/{authentikUserId}/recovery_email/",
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik;
|
||||
|
||||
public class AuthentikConfiguration
|
||||
{
|
||||
public string BaseUrl { get; set; } = string.Empty;
|
||||
public string ApiToken { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik;
|
||||
|
||||
public class AuthentikUserResponse
|
||||
{
|
||||
[JsonPropertyName("pk")]
|
||||
public int Pk { get; set; }
|
||||
|
||||
[JsonPropertyName("username")]
|
||||
public string Username { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("email")]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("is_active")]
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[JsonPropertyName("is_superuser")]
|
||||
public bool IsSuperuser { get; set; }
|
||||
|
||||
[JsonPropertyName("uid")]
|
||||
public string Uid { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using FictionArchive.Service.UserService.Services.AuthenticationClient.Authentik;
|
||||
|
||||
namespace FictionArchive.Service.UserService.Services.AuthenticationClient;
|
||||
|
||||
public interface IAuthenticationServiceClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new user in the authentication provider.
|
||||
/// </summary>
|
||||
/// <param name="username">The username for the new user</param>
|
||||
/// <param name="email">The email address for the new user</param>
|
||||
/// <param name="displayName">The display name for the new user</param>
|
||||
/// <returns>The created user response, or null if creation failed</returns>
|
||||
Task<AuthentikUserResponse?> CreateUserAsync(string username, string email, string displayName);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a password recovery email to the user.
|
||||
/// </summary>
|
||||
/// <param name="authentikUserId">The Authentik user ID (pk)</param>
|
||||
/// <returns>True if the email was sent successfully, false otherwise</returns>
|
||||
Task<bool> SendRecoveryEmailAsync(int authentikUserId);
|
||||
}
|
||||
Reference in New Issue
Block a user