Skip to content

Commit 55e6242

Browse files
feat(FilterAddressField): allow direct internal values
This commit allows FilterAddressField to return values directly instead of returning them in the usual filter address array format. This is primarily useful for fields who need the same valiadations as a normal filter address field but don't store the value as an array.
1 parent 397980a commit 55e6242

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Fields/FilterAddressField.inc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class FilterAddressField extends InterfaceField {
4242
* L2TP client.
4343
* @param bool $allow_pppoe Allow this field's value to be `pppoe`. This is used to indicate the address is any
4444
* PPPoE client.
45+
* @param bool $internal_direct If `true`, this field's value will be written as a direct value instead of
46+
* an array. This is useful for fields that need the same validation as this Field, but do not store their
47+
* values as the usual filter address array.
4548
* @param bool $allow_empty If `true`, empty strings will be allowed by this field.
4649
* @param bool $allow_null If `true`, null values will be allowed by this field.
4750
* @param array $interface_query Assigns query parameters to limit which interfaces should be accepted by this
@@ -102,6 +105,7 @@ class FilterAddressField extends InterfaceField {
102105
public bool $allow_self = true,
103106
public bool $allow_l2tp = true,
104107
public bool $allow_pppoe = true,
108+
public bool $internal_direct = false,
105109
bool $allow_empty = false,
106110
bool $allow_null = false,
107111
array $interface_query = [],
@@ -290,12 +294,12 @@ class FilterAddressField extends InterfaceField {
290294
$if_ip_modifier_set = false;
291295

292296
# When `any` is set, additional parameters are irrelevant. Set the `any` internal value and return it.
293-
if ($representation_value === 'any') {
297+
if ($representation_value === 'any' and !$this->internal_direct) {
294298
return ['any' => true];
295299
}
296300

297301
# Remove the prefixed invert character (!) and set its internal value if present
298-
if (str_starts_with($representation_value, self::INVERT_PREFIX)) {
302+
if (str_starts_with($representation_value, self::INVERT_PREFIX) and !$this->internal_direct) {
299303
$representation_value = substr($representation_value, 1);
300304
$internal_value['not'] = true;
301305
}
@@ -306,6 +310,11 @@ class FilterAddressField extends InterfaceField {
306310
$if_ip_modifier_set = true;
307311
}
308312

313+
# If this value has internal direct set, we can return it directly
314+
if ($this->internal_direct) {
315+
return $if_ip_modifier_set ? $representation_value . 'ip' : $representation_value;
316+
}
317+
309318
# Assign the `address` internal value for individual IP values, subnets, and aliases
310319
if ($this->has_label('is_ipaddr') or $this->has_label('is_subnet') or $this->has_label('is_alias')) {
311320
$internal_value[$this->internal_value_key] = $representation_value;
@@ -331,6 +340,15 @@ class FilterAddressField extends InterfaceField {
331340
# Assign a variable to use when piecing back together our representation value
332341
$representation_value = '';
333342

343+
# If this is a direct internal value, just check for the :ip modifier and return the value directly
344+
if ($this->internal_direct) {
345+
# If the value ends with `ip`, append the `:ip` modifier to the representation value
346+
if (str_ends_with($internal_value, 'ip')) {
347+
return substr($internal_value, 0, -2) . ':ip';
348+
}
349+
return $internal_value;
350+
}
351+
334352
# If the `any` flag is set, the representation value has to be `any`
335353
if (isset($internal_value['any'])) {
336354
return 'any';

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIFieldsFilterAddressFieldTestCase.inc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,29 @@ class APIFieldsFilterAddressFieldTestCase extends TestCase {
434434
# Delete the firewall alias
435435
$alias->delete();
436436
}
437+
438+
/**
439+
* Checks that the internal_direct option stores the field's value as a direct value instead of a normal filter
440+
* address array.
441+
*/
442+
public function test_internal_direct(): void {
443+
$field = new FilterAddressField(
444+
required: true,
445+
allow_ipaddr: true,
446+
allow_interface_ip: true,
447+
internal_direct: true,
448+
);
449+
450+
# Ensure the to_internal method returns the internal value directly
451+
$field->value = '1.2.3.4';
452+
$this->assert_equals($field->to_internal(), '1.2.3.4');
453+
$field->value = 'wan:ip';
454+
$this->assert_equals($field->to_internal(), 'wanip');
455+
456+
# Ensure the from_internal method populates the value correctly from a direct value
457+
$field->from_internal('1.2.3.4');
458+
$this->assert_equals($field->value, '1.2.3.4');
459+
$field->from_internal('wanip');
460+
$this->assert_equals($field->value, 'wan:ip');
461+
}
437462
}

0 commit comments

Comments
 (0)