Refactored subnet object methods and enhanced related documentation
This commit is contained in:
503
classlib.tests/Helpers/RequestHelperTests.cs
Normal file
503
classlib.tests/Helpers/RequestHelperTests.cs
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
namespace PS.IPAM.Tests.Helpers;
|
||||||
|
|
||||||
|
using System.Net;
|
||||||
|
using FluentAssertions;
|
||||||
|
using PS.IPAM;
|
||||||
|
using PS.IPAM.Helpers;
|
||||||
|
using PS.IPAM.Tests.Mocks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class RequestHelperTests : IDisposable
|
||||||
|
{
|
||||||
|
private MockHttpMessageHandler? _mockHandler;
|
||||||
|
|
||||||
|
public RequestHelperTests()
|
||||||
|
{
|
||||||
|
// Clean state before each test
|
||||||
|
SessionManager.CloseSession();
|
||||||
|
RequestHelper.TestHttpHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Clean up after each test
|
||||||
|
SessionManager.CloseSession();
|
||||||
|
RequestHelper.TestHttpHandler = null;
|
||||||
|
_mockHandler?.ForceDispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupSession(AuthType authType = AuthType.token)
|
||||||
|
{
|
||||||
|
if (authType == AuthType.token)
|
||||||
|
{
|
||||||
|
SessionManager.CreateSessionWithToken("https://ipam.example.com", "testapp", "test-token");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For credentials auth, we need to set up a session manually with future expiry
|
||||||
|
var session = new Session(
|
||||||
|
AuthType.credentials,
|
||||||
|
"cred-token",
|
||||||
|
"testapp",
|
||||||
|
"https://ipam.example.com",
|
||||||
|
DateTime.Now.AddHours(1),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
SessionManager.CurrentSession = session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MockHttpMessageHandler SetupMockHandler()
|
||||||
|
{
|
||||||
|
_mockHandler = new MockHttpMessageHandler();
|
||||||
|
RequestHelper.TestHttpHandler = _mockHandler;
|
||||||
|
return _mockHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithNoSession_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange - no session set up
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await action.Should().ThrowAsync<Exception>().WithMessage("No session available!");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithValidSession_BuildsCorrectUri()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{\"id\":1,\"ip\":\"192.168.1.1\"}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest.Should().NotBeNull();
|
||||||
|
handler.LastRequest!.RequestUri!.ToString().Should().Be("https://ipam.example.com/api/testapp/addresses/1/");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithSubController_BuildsCorrectUri()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("[]");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.subnets, null, subcontrollers.tags, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.RequestUri!.ToString().Should().Contain("/subnets/tags/1/");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithTokenAuth_AddsPhpipamTokenHeader()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession(AuthType.token);
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.GetLastRequestHeader("phpipam-token").Should().Be("test-token");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithCredentialsAuth_AddsTokenHeader()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession(AuthType.credentials);
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.GetLastRequestHeader("token").Should().Be("cred-token");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_GetMethod_UsesHttpGet()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Get);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_PostMethod_UsesHttpPost()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{\"id\":1}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, new { ip = "10.0.0.1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Post);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_PatchMethod_UsesHttpPatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{\"id\":1}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, new { description = "updated" }, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Method.Should().Be(new HttpMethod("PATCH"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_DeleteMethod_UsesHttpDelete()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_With404Response_ReturnsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithNotFoundResponse();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "999" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithErrorResponse_ThrowsHttpRequestException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithErrorResponse(HttpStatusCode.InternalServerError, "Server error");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await action.Should().ThrowAsync<HttpRequestException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithAddressType_ReturnsAddressObject()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var addressJson = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""subnetId"": 10,
|
||||||
|
""ip"": ""192.168.1.100"",
|
||||||
|
""is_gateway"": false,
|
||||||
|
""description"": ""Test server"",
|
||||||
|
""hostname"": ""server01"",
|
||||||
|
""mac"": ""00:11:22:33:44:55"",
|
||||||
|
""owner"": ""admin"",
|
||||||
|
""tag"": 2,
|
||||||
|
""deviceId"": 0,
|
||||||
|
""location"": """",
|
||||||
|
""port"": """",
|
||||||
|
""note"": """",
|
||||||
|
""lastSeen"": null,
|
||||||
|
""excludePing"": false,
|
||||||
|
""PTRignore"": false,
|
||||||
|
""PTR"": 0,
|
||||||
|
""firewallAddressObject"": """",
|
||||||
|
""editDate"": null,
|
||||||
|
""customer_id"": 0
|
||||||
|
}";
|
||||||
|
handler.WithSuccessResponse(addressJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeOfType<Address>();
|
||||||
|
var address = (Address)result!;
|
||||||
|
address.Id.Should().Be(1);
|
||||||
|
address.Ip.Should().Be("192.168.1.100");
|
||||||
|
address.Hostname.Should().Be("server01");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithAddressArray_ReturnsListOfAddresses()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var addressArrayJson = @"[
|
||||||
|
{""id"": 1, ""subnetId"": 10, ""ip"": ""192.168.1.1"", ""hostname"": ""host1""},
|
||||||
|
{""id"": 2, ""subnetId"": 10, ""ip"": ""192.168.1.2"", ""hostname"": ""host2""}
|
||||||
|
]";
|
||||||
|
handler.WithSuccessResponse(addressArrayJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Address, null, null, new[] { "10", "addresses" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeAssignableTo<IEnumerable<object>>();
|
||||||
|
var addresses = ((IEnumerable<object>)result!).ToList();
|
||||||
|
addresses.Should().HaveCount(2);
|
||||||
|
addresses[0].Should().BeOfType<Address>();
|
||||||
|
((Address)addresses[0]).Ip.Should().Be("192.168.1.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithVlanType_ReturnsVlanObject()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var vlanJson = @"{
|
||||||
|
""vlanId"": 100,
|
||||||
|
""domainId"": 1,
|
||||||
|
""name"": ""Production"",
|
||||||
|
""number"": 100,
|
||||||
|
""description"": ""Production VLAN"",
|
||||||
|
""editDate"": null,
|
||||||
|
""customer_id"": 0
|
||||||
|
}";
|
||||||
|
handler.WithSuccessResponse(vlanJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "100" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeOfType<Vlan>();
|
||||||
|
var vlan = (Vlan)result!;
|
||||||
|
vlan.Name.Should().Be("Production");
|
||||||
|
vlan.Number.Should().Be(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithSubnetworkType_ReturnsSubnetworkObject()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var subnetJson = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""subnet"": ""192.168.1.0"",
|
||||||
|
""mask"": 24,
|
||||||
|
""sectionId"": 1,
|
||||||
|
""description"": ""Test subnet"",
|
||||||
|
""linked_subnet"": """",
|
||||||
|
""firewallAddressObject"": """",
|
||||||
|
""vrfId"": 0,
|
||||||
|
""masterSubnetId"": 0,
|
||||||
|
""allowRequests"": false,
|
||||||
|
""vlanId"": 100,
|
||||||
|
""showName"": false,
|
||||||
|
""deviceId"": 0,
|
||||||
|
""permissions"": """",
|
||||||
|
""pingSubnet"": false,
|
||||||
|
""discoverSubnet"": false,
|
||||||
|
""resolveDNS"": false,
|
||||||
|
""DNSrecursive"": false,
|
||||||
|
""DNSrecords"": false,
|
||||||
|
""nameserverId"": 0,
|
||||||
|
""scanAgent"": false,
|
||||||
|
""isFolder"": false,
|
||||||
|
""isFull"": false,
|
||||||
|
""isPool"": false,
|
||||||
|
""state"": 1,
|
||||||
|
""threshold"": 0,
|
||||||
|
""location"": 0,
|
||||||
|
""editDate"": null,
|
||||||
|
""lastScan"": null,
|
||||||
|
""lastDiscovery"": null,
|
||||||
|
""calculation"": {}
|
||||||
|
}";
|
||||||
|
handler.WithSuccessResponse(subnetJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeOfType<Subnetwork>();
|
||||||
|
var subnet = (Subnetwork)result!;
|
||||||
|
subnet.Subnet.Should().Be("192.168.1.0");
|
||||||
|
subnet.Mask.Should().Be(24);
|
||||||
|
subnet.GetCIDR().Should().Be("192.168.1.0/24");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithSectionType_ReturnsSectionObject()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var sectionJson = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""name"": ""Production"",
|
||||||
|
""description"": ""Production section"",
|
||||||
|
""masterSection"": 0,
|
||||||
|
""permissions"": """",
|
||||||
|
""strictMode"": false,
|
||||||
|
""subnetOrdering"": ""default"",
|
||||||
|
""order"": 1,
|
||||||
|
""editDate"": null,
|
||||||
|
""showSubnet"": true,
|
||||||
|
""showVlan"": true,
|
||||||
|
""showVRF"": false,
|
||||||
|
""showSupernetOnly"": false,
|
||||||
|
""DNS"": 0
|
||||||
|
}";
|
||||||
|
handler.WithSuccessResponse(sectionJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeOfType<Section>();
|
||||||
|
var section = (Section)result!;
|
||||||
|
section.Name.Should().Be("Production");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithCustomFields_ParsesExtendedData()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
var addressJson = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""subnetId"": 10,
|
||||||
|
""ip"": ""192.168.1.100"",
|
||||||
|
""hostname"": ""server01"",
|
||||||
|
""custom_environment"": ""production"",
|
||||||
|
""custom_owner"": ""team-a""
|
||||||
|
}";
|
||||||
|
handler.WithSuccessResponse(addressJson);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var address = (Address)result!;
|
||||||
|
address.ExtendedData.Should().NotBeNull();
|
||||||
|
var extendedData = (Dictionary<string, object>)address.ExtendedData!;
|
||||||
|
extendedData.Should().ContainKey("custom_environment");
|
||||||
|
extendedData.Should().ContainKey("custom_owner");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithNoType_ReturnsDynamicData()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse(@"{""some"": ""data""}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.tools);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_PostWithParameters_SerializesJsonBody()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse(@"{""id"": 1}");
|
||||||
|
|
||||||
|
var parameters = new { ip = "10.0.0.1", subnetId = 5, description = "New address" };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, parameters);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Content.Should().NotBeNull();
|
||||||
|
var content = await handler.LastRequest.Content!.ReadAsStringAsync();
|
||||||
|
content.Should().Contain("10.0.0.1");
|
||||||
|
content.Should().Contain("subnetId");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_SetsAcceptJsonHeader()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
handler.LastRequest!.Headers.Accept.Should().Contain(h => h.MediaType == "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithEmptyResponse_ReturnsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithResponse(HttpStatusCode.OK, "", "application/json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InvokeRequest_WithNullDataInResponse_ReturnsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SetupSession();
|
||||||
|
var handler = SetupMockHandler();
|
||||||
|
handler.WithJsonResponse(@"{""code"": 200, ""success"": true, ""data"": null}");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
193
classlib.tests/Helpers/SessionManagerTests.cs
Normal file
193
classlib.tests/Helpers/SessionManagerTests.cs
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
namespace PS.IPAM.Tests.Helpers;
|
||||||
|
|
||||||
|
using FluentAssertions;
|
||||||
|
using PS.IPAM;
|
||||||
|
using PS.IPAM.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class SessionManagerTests : IDisposable
|
||||||
|
{
|
||||||
|
public SessionManagerTests()
|
||||||
|
{
|
||||||
|
// Ensure clean state before each test
|
||||||
|
SessionManager.CloseSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Clean up after each test
|
||||||
|
SessionManager.CloseSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSession_WhenNoSession_ReturnsNoToken()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SessionManager.CurrentSession = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SessionManager.TestSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("NoToken");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSession_WhenSessionWithNullExpires_ReturnsValid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var session = new Session(AuthType.token, "test-token", "app", "https://test.com", null, null);
|
||||||
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SessionManager.TestSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSession_WhenSessionNotExpired_ReturnsValid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var futureExpiry = DateTime.Now.AddHours(1);
|
||||||
|
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", futureExpiry, null);
|
||||||
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SessionManager.TestSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestSession_WhenSessionExpired_ReturnsExpired()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var pastExpiry = DateTime.Now.AddHours(-1);
|
||||||
|
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", pastExpiry, null);
|
||||||
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SessionManager.TestSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Expired");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateSessionWithToken_CreatesValidSession()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var url = "https://ipam.example.com";
|
||||||
|
var appId = "myApp";
|
||||||
|
var token = "static-api-token";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var session = SessionManager.CreateSessionWithToken(url, appId, token);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
session.Should().NotBeNull();
|
||||||
|
session.URL.Should().Be(url);
|
||||||
|
session.AppID.Should().Be(appId);
|
||||||
|
session.Token.Should().Be(token);
|
||||||
|
session.AuthType.Should().Be(AuthType.token);
|
||||||
|
session.Expires.Should().BeNull();
|
||||||
|
session.Credentials.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateSessionWithToken_SetsCurrentSession()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var url = "https://ipam.example.com";
|
||||||
|
var appId = "myApp";
|
||||||
|
var token = "api-token";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var session = SessionManager.CreateSessionWithToken(url, appId, token);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
SessionManager.CurrentSession.Should().BeSameAs(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CloseSession_ClearsCurrentSession()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SessionManager.CreateSessionWithToken("https://test.com", "app", "token");
|
||||||
|
SessionManager.CurrentSession.Should().NotBeNull();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
SessionManager.CloseSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
SessionManager.CurrentSession.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CloseSession_WhenNoSession_DoesNotThrow()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SessionManager.CurrentSession = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var action = () => SessionManager.CloseSession();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
action.Should().NotThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CurrentSession_CanBeSetDirectly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var session = new Session(AuthType.token, "token", "app", "https://test.com", null, null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
SessionManager.CurrentSession.Should().BeSameAs(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateHttpClient_WithoutIgnoreSsl_ReturnsHttpClient()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
using var client = SessionManager.CreateHttpClient(false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
client.Should().NotBeNull();
|
||||||
|
client.Should().BeOfType<HttpClient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateHttpClient_WithIgnoreSsl_ReturnsHttpClient()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
using var client = SessionManager.CreateHttpClient(true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
client.Should().NotBeNull();
|
||||||
|
client.Should().BeOfType<HttpClient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateSessionWithToken_ReplacesExistingSession()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
SessionManager.CreateSessionWithToken("https://old.com", "oldApp", "oldToken");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var newSession = SessionManager.CreateSessionWithToken("https://new.com", "newApp", "newToken");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
SessionManager.CurrentSession.Should().BeSameAs(newSession);
|
||||||
|
SessionManager.CurrentSession!.URL.Should().Be("https://new.com");
|
||||||
|
SessionManager.CurrentSession.AppID.Should().Be("newApp");
|
||||||
|
SessionManager.CurrentSession.Token.Should().Be("newToken");
|
||||||
|
}
|
||||||
|
}
|
||||||
32
classlib.tests/TestCollections.cs
Normal file
32
classlib.tests/TestCollections.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
namespace PS.IPAM.Tests;
|
||||||
|
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Collection definition for tests that share static state (SessionManager, RequestHelper.TestHttpHandler).
|
||||||
|
/// Tests in this collection will run sequentially, not in parallel.
|
||||||
|
/// </summary>
|
||||||
|
[CollectionDefinition("Sequential")]
|
||||||
|
public class SequentialCollection : ICollectionFixture<SequentialTestFixture>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fixture for sequential test collection.
|
||||||
|
/// </summary>
|
||||||
|
public class SequentialTestFixture : IDisposable
|
||||||
|
{
|
||||||
|
public SequentialTestFixture()
|
||||||
|
{
|
||||||
|
// Clean up before tests
|
||||||
|
PS.IPAM.Helpers.SessionManager.CloseSession();
|
||||||
|
PS.IPAM.Helpers.RequestHelper.TestHttpHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Clean up after tests
|
||||||
|
PS.IPAM.Helpers.SessionManager.CloseSession();
|
||||||
|
PS.IPAM.Helpers.RequestHelper.TestHttpHandler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
374
classlib/Helpers/RequestHelper.cs
Normal file
374
classlib/Helpers/RequestHelper.cs
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
namespace PS.IPAM.Helpers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PS.IPAM;
|
||||||
|
|
||||||
|
public static class RequestHelper
|
||||||
|
{
|
||||||
|
// Handler for testing - allows injecting a mock HTTP handler
|
||||||
|
public static HttpMessageHandler? TestHttpHandler { get; set; }
|
||||||
|
|
||||||
|
public static async Task<object?> InvokeRequest(
|
||||||
|
string method,
|
||||||
|
controllers controller,
|
||||||
|
types? type = null,
|
||||||
|
subcontrollers? subController = null,
|
||||||
|
object? parameters = null,
|
||||||
|
string[]? identifiers = null,
|
||||||
|
bool ignoreSsl = false)
|
||||||
|
{
|
||||||
|
var tokenStatus = SessionManager.TestSession();
|
||||||
|
if (tokenStatus == "NoToken")
|
||||||
|
{
|
||||||
|
throw new Exception("No session available!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenStatus == "Expired")
|
||||||
|
{
|
||||||
|
await UpdateSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
var session = SessionManager.CurrentSession;
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
throw new Exception("No session available!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var uri = $"{session.URL}/api/{session.AppID}/{controller}";
|
||||||
|
if (subController != null)
|
||||||
|
{
|
||||||
|
uri += $"/{subController}";
|
||||||
|
}
|
||||||
|
if (identifiers != null && identifiers.Length > 0)
|
||||||
|
{
|
||||||
|
uri += $"/{string.Join("/", identifiers)}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
using var client = SessionManager.CreateHttpClient(ignoreSsl, TestHttpHandler);
|
||||||
|
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
|
||||||
|
switch (session.AuthType)
|
||||||
|
{
|
||||||
|
case AuthType.credentials:
|
||||||
|
client.DefaultRequestHeaders.Add("token", session.Token);
|
||||||
|
break;
|
||||||
|
case AuthType.token:
|
||||||
|
client.DefaultRequestHeaders.Add("phpipam-token", session.Token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponseMessage? response = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (method == "GET")
|
||||||
|
{
|
||||||
|
response = await client.GetAsync(uri);
|
||||||
|
}
|
||||||
|
else if (method == "POST")
|
||||||
|
{
|
||||||
|
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
||||||
|
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||||
|
response = await client.PostAsync(uri, content);
|
||||||
|
}
|
||||||
|
else if (method == "PATCH")
|
||||||
|
{
|
||||||
|
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
||||||
|
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||||
|
var request = new HttpRequestMessage(new HttpMethod("PATCH"), uri)
|
||||||
|
{
|
||||||
|
Content = content
|
||||||
|
};
|
||||||
|
response = await client.SendAsync(request);
|
||||||
|
}
|
||||||
|
else if (method == "DELETE")
|
||||||
|
{
|
||||||
|
response = await client.DeleteAsync(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new HttpRequestException($"Request failed with status {response.StatusCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(responseContent))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(responseContent);
|
||||||
|
if (jsonResponse == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.HasValue)
|
||||||
|
{
|
||||||
|
return ConvertToTypedObjects(jsonResponse, type.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse.data;
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
if (ex.Message.Contains("404"))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? ConvertToTypedObjects(dynamic jsonResponse, types type)
|
||||||
|
{
|
||||||
|
if (jsonResponse?.data == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = jsonResponse.data;
|
||||||
|
if (data is JArray array)
|
||||||
|
{
|
||||||
|
return array.Select(item => ConvertSingleObject(item, type)).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ConvertSingleObject(data, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? ConvertSingleObject(dynamic item, types type)
|
||||||
|
{
|
||||||
|
var jobject = item as JObject;
|
||||||
|
if (jobject == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var customFields = new Dictionary<string, object>();
|
||||||
|
foreach (var prop in jobject.Properties())
|
||||||
|
{
|
||||||
|
if (prop.Name.StartsWith("custom_"))
|
||||||
|
{
|
||||||
|
customFields[prop.Name] = prop.Value?.ToObject<object>() ?? new object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case types.Address:
|
||||||
|
return CreateAddress(jobject, customFields);
|
||||||
|
case types.Vlan:
|
||||||
|
return CreateVlan(jobject, customFields);
|
||||||
|
case types.Subnetwork:
|
||||||
|
return CreateSubnetwork(jobject, customFields);
|
||||||
|
case types.Vrf:
|
||||||
|
return CreateVrf(jobject, customFields);
|
||||||
|
case types.Section:
|
||||||
|
return CreateSection(jobject);
|
||||||
|
case types.Tag:
|
||||||
|
return CreateTag(jobject);
|
||||||
|
case types.Nameserver:
|
||||||
|
return CreateNameserver(jobject);
|
||||||
|
case types.Domain:
|
||||||
|
return CreateDomain(jobject);
|
||||||
|
default:
|
||||||
|
return jobject.ToObject<object>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Address CreateAddress(JObject jobject, Dictionary<string, object> customFields)
|
||||||
|
{
|
||||||
|
return new Address(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["subnetId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["ip"]?.ToString() ?? "",
|
||||||
|
jobject["is_gateway"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["hostname"]?.ToString() ?? "",
|
||||||
|
jobject["mac"]?.ToString() ?? "",
|
||||||
|
jobject["owner"]?.ToString() ?? "",
|
||||||
|
jobject["tag"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["location"]?.ToString() ?? "",
|
||||||
|
jobject["port"]?.ToString() ?? "",
|
||||||
|
jobject["note"]?.ToString() ?? "",
|
||||||
|
jobject["lastSeen"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["excludePing"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["PTRignore"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["PTR"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["firewallAddressObject"]?.ToString() ?? "",
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
||||||
|
customFields.Count > 0 ? customFields : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vlan CreateVlan(JObject jobject, Dictionary<string, object> customFields)
|
||||||
|
{
|
||||||
|
return new Vlan(
|
||||||
|
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["domainId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["name"]?.ToString() ?? "",
|
||||||
|
jobject["number"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
||||||
|
customFields.Count > 0 ? customFields : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Subnetwork CreateSubnetwork(JObject jobject, Dictionary<string, object> customFields)
|
||||||
|
{
|
||||||
|
var props = jobject.Properties().ToList();
|
||||||
|
return new Subnetwork(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["subnet"]?.ToString() ?? "",
|
||||||
|
jobject["mask"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["sectionId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["linked_subnet"]?.ToString() ?? "",
|
||||||
|
jobject["firewallAddressObject"]?.ToString() ?? "",
|
||||||
|
jobject["vrfId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["masterSubnetId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["allowRequests"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["showName"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["permissions"]?.ToString() ?? "",
|
||||||
|
jobject["pingSubnet"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["discoverSubnet"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["resolveDNS"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["DNSrecursive"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["DNSrecords"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["nameserverId"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["scanAgent"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["isFolder"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["isFull"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["isPool"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["state"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["threshold"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["location"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["lastScan"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["lastDiscovery"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["calculation"]?.ToObject<object>() ?? new object(),
|
||||||
|
customFields.Count > 0 ? customFields : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vrf CreateVrf(JObject jobject, Dictionary<string, object> customFields)
|
||||||
|
{
|
||||||
|
return new Vrf(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["name"]?.ToString() ?? "",
|
||||||
|
jobject["rd"]?.ToString() ?? "",
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["sections"]?.ToString() ?? "",
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||||
|
customFields.Count > 0 ? customFields : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Section CreateSection(JObject jobject)
|
||||||
|
{
|
||||||
|
return new Section(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["name"]?.ToString() ?? "",
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["masterSection"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["permissions"]?.ToString() ?? "",
|
||||||
|
jobject["strictMode"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["subnetOrdering"]?.ToString() ?? "",
|
||||||
|
jobject["order"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||||
|
jobject["showSubnet"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["showVlan"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["showVRF"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["showSupernetOnly"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["DNS"]?.ToObject<int>() ?? 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Tag CreateTag(JObject jobject)
|
||||||
|
{
|
||||||
|
return new Tag(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["type"]?.ToString() ?? "",
|
||||||
|
jobject["showtag"]?.ToObject<bool>() ?? false,
|
||||||
|
jobject["bgcolor"]?.ToString() ?? "",
|
||||||
|
jobject["fgcolor"]?.ToString() ?? "",
|
||||||
|
jobject["compress"]?.ToString() ?? "",
|
||||||
|
jobject["locked"]?.ToString() ?? "",
|
||||||
|
jobject["updateTag"]?.ToObject<bool>() ?? false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Nameserver CreateNameserver(JObject jobject)
|
||||||
|
{
|
||||||
|
return new Nameserver(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["name"]?.ToString() ?? "",
|
||||||
|
jobject["nameservers"]?.ToString() ?? "",
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["permissions"]?.ToString() ?? "",
|
||||||
|
jobject["editDate"]?.ToObject<DateTime?>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Domain CreateDomain(JObject jobject)
|
||||||
|
{
|
||||||
|
return new Domain(
|
||||||
|
jobject["id"]?.ToObject<int>() ?? 0,
|
||||||
|
jobject["name"]?.ToString() ?? "",
|
||||||
|
jobject["description"]?.ToString() ?? "",
|
||||||
|
jobject["sections"]?.ToString() ?? ""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task UpdateSession()
|
||||||
|
{
|
||||||
|
var session = SessionManager.CurrentSession;
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
throw new Exception("No session available!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var tokenStatus = SessionManager.TestSession();
|
||||||
|
if (tokenStatus == "Valid")
|
||||||
|
{
|
||||||
|
// Just refresh the token
|
||||||
|
var result = await InvokeRequest("PATCH", controllers.user, null, null, null, null);
|
||||||
|
// Token refresh doesn't return expires in the same format, so we'll skip updating expires
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenStatus == "Expired" && session.Credentials is PSCredential creds)
|
||||||
|
{
|
||||||
|
await SessionManager.CreateSessionWithCredentials(
|
||||||
|
session.URL,
|
||||||
|
session.AppID,
|
||||||
|
creds,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user