From d333b43d8af6f46caddf76f5c95e9d4b00e555d2 Mon Sep 17 00:00:00 2001 From: Jared Hendrickson Date: Tue, 17 Dec 2024 21:50:13 -0700 Subject: [PATCH] fix: use queries to check for nested aliases #619 --- .../pkg/RESTAPI/Models/FirewallAlias.inc | 31 +++++++++++-------- .../Tests/APIModelsFirewallAliasTestCase.inc | 18 +++++++++++ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/FirewallAlias.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/FirewallAlias.inc index dd417aa18..b626884b5 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/FirewallAlias.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/FirewallAlias.inc @@ -93,34 +93,39 @@ class FirewallAlias extends Model { * @returns string The validated value to set. * @throws ValidationError When the `address` value is invalid. */ - public function validate_address(string $addresses): string { + public function validate_address(string $address): string { + # Variables + $aliases = $this->read_all(); + $type = $this->type->value; + # Ensure value is a port, port range or port alias when `type` is `port` - if ($this->type->value === 'port' and !is_port_or_range_or_alias($addresses)) { + $port_alias_q = $aliases->query(name: $address, type: 'port'); + if ($type === 'port' and !is_port_or_range($address) and !$port_alias_q->exists()) { throw new ValidationError( - message: "Port alias 'address' value '$addresses' is not a valid port, range, or alias.", + message: "Port alias 'address' value '$address' is not a valid port, range, or alias.", response_id: 'INVALID_PORT_ALIAS_ADDRESS', ); } # Ensure value is an IP, FQDN or alias when `type` is `host` - if ($this->type->value === 'host' and !is_ipaddroralias($addresses) and !is_fqdn($addresses)) { + $host_alias_q = $aliases->query(name: $address, type: 'host'); + if ($type === 'host' and !is_ipaddr($address) and !is_fqdn($address) and !$host_alias_q->exists()) { throw new ValidationError( - message: "Host alias 'address' value '$addresses' is not a valid IP, FQDN, or alias.", + message: "Host alias 'address' value '$address' is not a valid IP, FQDN, or alias.", response_id: 'INVALID_HOST_ALIAS_ADDRESS', ); } # Ensure value is a CIDR, FQDN or alias when `type` is `network` - if ($this->type->value === 'network') { - if (!is_subnet($addresses) and alias_get_type($addresses) != 'network' and !is_fqdn($addresses)) { - throw new ValidationError( - message: "Host alias 'address' value '$addresses' is not a valid CIDR, FQDN, or alias.", - response_id: 'INVALID_NETWORK_ALIAS_ADDRESS', - ); - } + $network_alias_q = $aliases->query(name: $address, type: 'network'); + if ($type === 'network' and !is_subnet($address) and !is_fqdn($address) and !$network_alias_q->exists()) { + throw new ValidationError( + message: "Host alias 'address' value '$address' is not a valid CIDR, FQDN, or alias.", + response_id: 'INVALID_NETWORK_ALIAS_ADDRESS', + ); } - return $addresses; + return $address; } /** diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsFirewallAliasTestCase.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsFirewallAliasTestCase.inc index 21c5591c4..c98d8e425 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsFirewallAliasTestCase.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsFirewallAliasTestCase.inc @@ -144,4 +144,22 @@ class APIModelsFirewallAliasTestCase extends TestCase { }, ); } + + /** + * Checks that we can reference a nested alias during replace_all() calls. This is regression test for #619. + */ + public function test_nested_alias_reference_in_replace_all(): void { + # Ensure we can reference a nested alias during replace_all() calls without an error being thrown + $this->assert_does_not_throw( + callable: function () { + $alias = new FirewallAlias(); + $alias->replace_all( + data: [ + ['name' => 'test_alias1', 'type' => 'host', 'address' => []], + ['name' => 'test_alias2', 'type' => 'host', 'address' => ['test_alias1']], + ], + ); + }, + ); + } }