166 lines
4.9 KiB
C#
166 lines
4.9 KiB
C#
namespace PS.IPAM.Helpers;
|
|
|
|
using System;
|
|
using System.Management.Automation;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json;
|
|
|
|
/// <summary>
|
|
/// Manages phpIPAM API sessions including creation, validation, and lifecycle.
|
|
/// </summary>
|
|
public static class SessionManager
|
|
{
|
|
private static Session? _currentSession;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the current active session.
|
|
/// </summary>
|
|
public static Session? CurrentSession
|
|
{
|
|
get => _currentSession;
|
|
set => _currentSession = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests the current session status.
|
|
/// </summary>
|
|
/// <returns>The session status indicating validity or issues.</returns>
|
|
public static SessionStatus GetSessionStatus()
|
|
{
|
|
if (_currentSession == null)
|
|
{
|
|
return SessionStatus.NoSession;
|
|
}
|
|
|
|
if (_currentSession.Expires == null)
|
|
{
|
|
return SessionStatus.Valid;
|
|
}
|
|
|
|
return _currentSession.Expires < DateTime.Now
|
|
? SessionStatus.Expired
|
|
: SessionStatus.Valid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new session using username/password credentials.
|
|
/// </summary>
|
|
/// <param name="url">The phpIPAM server URL.</param>
|
|
/// <param name="appId">The API application ID.</param>
|
|
/// <param name="credentials">The PowerShell credential object.</param>
|
|
/// <param name="ignoreSsl">Whether to ignore SSL certificate errors.</param>
|
|
/// <returns>The created session.</returns>
|
|
public static async Task<Session> CreateSessionWithCredentialsAsync(
|
|
string url,
|
|
string appId,
|
|
PSCredential credentials,
|
|
bool ignoreSsl = false)
|
|
{
|
|
var uri = $"{url}/api/{appId}/user";
|
|
var auth = Convert.ToBase64String(
|
|
Encoding.UTF8.GetBytes($"{credentials.UserName}:{GetPasswordString(credentials)}"));
|
|
|
|
using var client = CreateHttpClient(ignoreSsl);
|
|
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
|
|
|
|
var response = await client.PostAsync(uri, null);
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(content);
|
|
|
|
if (jsonResponse?.success != true)
|
|
{
|
|
throw new InvalidOperationException(
|
|
jsonResponse?.error?.ToString() ?? "Failed to create session");
|
|
}
|
|
|
|
var token = jsonResponse.data.token.ToString();
|
|
var expires = DateTime.Parse(jsonResponse.data.expires.ToString());
|
|
|
|
_currentSession = new Session(
|
|
AuthType.Credentials,
|
|
token,
|
|
appId,
|
|
url,
|
|
expires,
|
|
credentials
|
|
);
|
|
|
|
return _currentSession;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new session using a static API token.
|
|
/// </summary>
|
|
/// <param name="url">The phpIPAM server URL.</param>
|
|
/// <param name="appId">The API application ID.</param>
|
|
/// <param name="token">The API token.</param>
|
|
/// <returns>The created session.</returns>
|
|
public static Session CreateSessionWithToken(string url, string appId, string token)
|
|
{
|
|
_currentSession = new Session(
|
|
AuthType.Token,
|
|
token,
|
|
appId,
|
|
url,
|
|
null,
|
|
null
|
|
);
|
|
|
|
return _currentSession;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Closes the current session and clears session data.
|
|
/// </summary>
|
|
public static void CloseSession()
|
|
{
|
|
_currentSession = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an HttpClient with optional SSL bypass.
|
|
/// </summary>
|
|
/// <param name="ignoreSsl">Whether to ignore SSL certificate errors.</param>
|
|
/// <param name="handler">Optional custom message handler for testing.</param>
|
|
/// <returns>A configured HttpClient instance.</returns>
|
|
public static HttpClient CreateHttpClient(bool ignoreSsl = false, HttpMessageHandler? handler = null)
|
|
{
|
|
if (handler != null)
|
|
{
|
|
return new HttpClient(handler);
|
|
}
|
|
|
|
if (ignoreSsl)
|
|
{
|
|
var sslHandler = new HttpClientHandler
|
|
{
|
|
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
|
};
|
|
return new HttpClient(sslHandler);
|
|
}
|
|
|
|
return new HttpClient();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extracts the plain text password from a PSCredential object.
|
|
/// </summary>
|
|
private static string GetPasswordString(PSCredential credential)
|
|
{
|
|
var ptr = Marshal.SecureStringToBSTR(credential.Password);
|
|
try
|
|
{
|
|
return Marshal.PtrToStringBSTR(ptr);
|
|
}
|
|
finally
|
|
{
|
|
Marshal.ZeroFreeBSTR(ptr);
|
|
}
|
|
}
|
|
}
|