diff --git a/src/main/java/network/crypta/clients/http/SimpleToadletServer.java b/src/main/java/network/crypta/clients/http/SimpleToadletServer.java index c9e1237f21..e109716462 100644 --- a/src/main/java/network/crypta/clients/http/SimpleToadletServer.java +++ b/src/main/java/network/crypta/clients/http/SimpleToadletServer.java @@ -533,8 +533,10 @@ public SimpleToadletServer( // installation. configItemOrder = registerConnectionOptions(fproxyConfig, configItemOrder); - allowedFullAccess = new AllowedHosts(fproxyConfig.getString("allowedHostsFullAccess")); configItemOrder = registerAccessOptions(fproxyConfig, configItemOrder); + // Read only after registration so persistent values are visible instead of missing-option + // fallback. + allowedFullAccess = new AllowedHosts(fproxyConfig.getString("allowedHostsFullAccess")); configItemOrder = registerFilterAndLimitOptions(fproxyConfig, configItemOrder); diff --git a/src/test/java/network/crypta/clients/http/SimpleToadletServerTest.java b/src/test/java/network/crypta/clients/http/SimpleToadletServerTest.java index 86503cc4f5..2ba4c59c42 100644 --- a/src/test/java/network/crypta/clients/http/SimpleToadletServerTest.java +++ b/src/test/java/network/crypta/clients/http/SimpleToadletServerTest.java @@ -3,6 +3,7 @@ import java.net.InetAddress; import java.net.URI; import network.crypta.config.Config; +import network.crypta.config.PersistentConfig; import network.crypta.config.SubConfig; import network.crypta.io.NetworkInterface; import network.crypta.io.SSLNetworkInterface; @@ -10,6 +11,7 @@ import network.crypta.node.NodeClientCore; import network.crypta.support.HTMLNode; import network.crypta.support.PriorityAwareExecutor; +import network.crypta.support.SimpleFieldSet; import network.crypta.support.api.BucketFactory; import network.crypta.support.io.ArrayBucketFactory; import org.junit.jupiter.api.Test; @@ -134,6 +136,42 @@ void isAllowedFullAccess_whenAddressMatchesAllowList_returnsTrue() throws Except assertFalse(server.isAllowedFullAccess(InetAddress.getByName("8.8.8.8"))); } + @Test + void allowedHostsFullAccess_whenLoadedFromPersistentConfig_expectConfiguredValueRetained() + throws Exception { + // Arrange + String configuredHost = "192.0.2.44"; + SimpleFieldSet initial = new SimpleFieldSet(true); + initial.putSingle("fproxy.allowedHostsFullAccess", configuredHost); + PersistentConfig rootConfig = new PersistentConfig(initial); + SubConfig config = rootConfig.createSubConfig("fproxy"); + Node node = mock(Node.class, org.mockito.Answers.RETURNS_DEEP_STUBS); + BucketFactory bucketFactory = mock(BucketFactory.class); + PriorityAwareExecutor executor = mock(PriorityAwareExecutor.class); + + SimpleToadletServer server; + try (MockedStatic netMock = mockStatic(NetworkInterface.class); + MockedStatic sslMock = mockStatic(SSLNetworkInterface.class)) { + NetworkInterface iface = mock(NetworkInterface.class); + netMock + .when(() -> NetworkInterface.create(anyInt(), any(), any(), any(), anyBoolean())) + .thenReturn(iface); + sslMock + .when(() -> SSLNetworkInterface.createSsl(anyInt(), any(), any(), any(), anyBoolean())) + .thenReturn(iface); + server = new SimpleToadletServer(config, bucketFactory, executor, node); + } + + // Act + config.finishedInitialization(); + String callbackValue = config.getString("allowedHostsFullAccess"); + + // Assert + assertEquals(configuredHost, callbackValue); + assertTrue(server.isAllowedFullAccess(InetAddress.getByName(configuredHost))); + assertFalse(server.isAllowedFullAccess(InetAddress.getLoopbackAddress())); + } + @SuppressWarnings({"resource", "MustBeClosedChecker"}) private SimpleToadletServer newServerWithDefaults() throws Exception { Config rootConfig = new Config();