Skip to content

Commit df1311d

Browse files
Merge pull request #586 from jaredhendrickson13/next_patch
v2.2.1 Fixes & Features
2 parents 8668101 + 791e453 commit df1311d

File tree

10 files changed

+104
-12
lines changed

10 files changed

+104
-12
lines changed

docs/COMMON_CONTROL_PARAMETERS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ parameters you can use:
8181
you want to remove from. Then, make another request for the fields you want to replace.
8282

8383
!!! Notes
84-
- This parameter is only available for `PATCH` requests.
85-
- This parameter is only applicable to array fields.
86-
- If the submitted array values match the existing array values exactly, the API will not make any changes to that field to avoid removing all values unintentionally.
84+
- This parameter is only available for `PATCH` requests.
85+
- This parameter is only applicable to array fields.
86+
- If the submitted array values match the existing array values exactly, the API will not make any changes to that field to avoid removing all values unintentionally.
8787

8888
## reverse
8989

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Core/Model.inc

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -936,13 +936,8 @@ class Model {
936936

937937
# Loop through each of this Model's Fields and add its value to a serializable array
938938
foreach ($this->get_fields() as $field) {
939-
# Skip adding this field if it's a write only field
940-
if ($this->$field->write_only) {
941-
continue;
942-
}
943-
944-
# Skip adding this field if it is sensitive and sensitive fields are not exposed
945-
if ($this->$field->sensitive and !$expose_sensitive_fields) {
939+
# Skip adding this field if it's hidden
940+
if ($this->is_field_hidden($field)) {
946941
continue;
947942
}
948943

@@ -1063,6 +1058,42 @@ class Model {
10631058
return null;
10641059
}
10651060

1061+
/**
1062+
* Determines if a given Model field should be hidden in responses.
1063+
* @param string $field The field name to check for sensitivity.
1064+
* @return bool Returns true if the field is sensitive, false if it is not.
1065+
*/
1066+
private function is_field_hidden(string $field): bool {
1067+
# Variable
1068+
$pkg_config = RESTAPI\Models\RESTAPISettings::get_pkg_config();
1069+
$expose_sensitive_fields = $pkg_config['expose_sensitive_fields'] === 'enabled';
1070+
$overridden_sensitive_fields = explode(',', $pkg_config['override_sensitive_fields']);
1071+
$model_field_mapping = "{$this->get_class_shortname()}:$field";
1072+
1073+
# Field is hidden if it is 'write_only'
1074+
if ($this->$field->write_only) {
1075+
return true;
1076+
}
1077+
1078+
# Field is not hidden if the sensitive property is not set
1079+
if (!$this->$field->sensitive) {
1080+
return false;
1081+
}
1082+
1083+
# Field is not hidden if the 'expose_sensitive_fields' setting is enabled
1084+
if ($expose_sensitive_fields) {
1085+
return false;
1086+
}
1087+
1088+
# Field is not hidden if the field is in the 'override_sensitive_fields' setting
1089+
if (in_array($model_field_mapping, $overridden_sensitive_fields)) {
1090+
return false;
1091+
}
1092+
1093+
# Field is hidden if none of the above conditions are met
1094+
return true;
1095+
}
1096+
10661097
/**
10671098
* Determines if this Model applies changes immediately or if they must applied manually after changes are made.
10681099
* This is intended to be used to more accurately determine the 'Applies immediately' value in the API documentation

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Dispatchers/RESTAPISettingsSyncDispatcher.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use RESTAPI\Models\RESTAPISettingsSync;
1010
*/
1111
class RESTAPISettingsSyncDispatcher extends Dispatcher {
1212
public int $timeout = 60;
13+
public int $max_queue = 1024;
1314

1415
/**
1516
* Starts the REST API settings sync to HA peers.

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Forms/SystemRESTAPISettingsForm.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class SystemRESTAPISettingsForm extends Form {
3434
'login_protection',
3535
'log_successful_auth',
3636
'expose_sensitive_fields',
37+
'override_sensitive_fields',
3738
],
3839
],
3940
'Advanced Settings' => [

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/DHCPServerStaticMapping.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class DHCPServerStaticMapping extends Model {
4141
$this->config_path = 'staticmap';
4242
$this->subsystem = 'dhcpd';
4343
$this->many = true;
44+
$this->sort_by = ['ipaddr'];
4445

4546
# Define model Fields
4647
$this->mac = new StringField(

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/IPsecPhase1.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class IPsecPhase1 extends Model {
110110
);
111111
$this->myid_type = new StringField(
112112
required: true,
113-
choices: ['myaddress', 'address', 'fqdn', 'user_fqdn', 'asn1dn', 'keyid tag', 'dyn_dns'],
113+
choices: ['myaddress', 'address', 'fqdn', 'user_fqdn', 'asn1dn', 'keyid tag', 'dyn_dns', 'auto'],
114114
help_text: 'The identifier type used by the local end of the tunnel.',
115115
);
116116
$this->myid_data = new StringField(
@@ -121,7 +121,7 @@ class IPsecPhase1 extends Model {
121121
);
122122
$this->peerid_type = new StringField(
123123
required: true,
124-
choices: ['any', 'peeraddress', 'address', 'fqdn', 'user_fqdn', 'asn1dn', 'keyid tag', 'dyn_dns'],
124+
choices: ['any', 'peeraddress', 'address', 'fqdn', 'user_fqdn', 'asn1dn', 'keyid tag', 'dyn_dns', 'auto'],
125125
help_text: 'The identifier type used by the remote end of the tunnel.',
126126
);
127127
$this->peerid_data = new StringField(

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Models/RESTAPISettings.inc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class RESTAPISettings extends Model {
3434
public BooleanField $allow_pre_releases;
3535
public BooleanField $hateoas;
3636
public BooleanField $expose_sensitive_fields;
37+
public StringField $override_sensitive_fields;
3738
public InterfaceField $allowed_interfaces;
3839
public StringField $represent_interfaces_as;
3940
public StringField $auth_methods;
@@ -119,6 +120,15 @@ class RESTAPISettings extends Model {
119120
help_text: 'Enables or disables exposing sensitive fields in API responses. When enabled, sensitive fields ' .
120121
'such as passwords, private keys, and other sensitive data will be included in API responses.',
121122
);
123+
$this->override_sensitive_fields = new StringField(
124+
default: [],
125+
choices_callable: 'get_override_sensitive_fields_choices',
126+
many: true,
127+
conditions: ['expose_sensitive_fields' => false],
128+
help_text: 'Specifies a list of fields (formatted as ModelName:FieldName) that should have their sensitive ' .
129+
'attribute overridden. Fields selected here will not be considered sensitive and will be included in ' .
130+
'API responses regardless of the `expose_sensitive_fields` setting.',
131+
);
122132
$this->allowed_interfaces = new InterfaceField(
123133
default: [],
124134
allow_localhost_interface: true,
@@ -215,6 +225,28 @@ class RESTAPISettings extends Model {
215225
return $choices;
216226
}
217227

228+
/**
229+
* Obtains the choices for the `override_sensitive_fields` field. This will dynamically populate a choice for each
230+
* Model and Field in the \RESTAPI\Models namespace.
231+
*/
232+
public function get_override_sensitive_fields_choices(): array {
233+
# Variables
234+
$choices = [];
235+
236+
# Format choices so they include the class's verbose name as the choice's verbose name
237+
foreach (get_classes_from_namespace(namespace: '\\RESTAPI\\Models\\') as $model_class) {
238+
$model = new $model_class();
239+
foreach ($model->get_fields() as $field) {
240+
if ($model->$field->sensitive) {
241+
$choices[$model->get_class_shortname() . ':' . $field] =
242+
$model->get_class_shortname() . ':' . $field;
243+
}
244+
}
245+
}
246+
247+
return $choices;
248+
}
249+
218250
/**
219251
* Creates a backup of the current API configuration at /usr/local/share/pfSense-pkg-RESTAPI/backup.json.
220252
* @returns integer Returns 0 when backup was successful, or -1 when the API's `keep_backup` field is disabled.

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,4 +567,26 @@ class APIModelsAPISettingsTestCase extends TestCase {
567567
$user = new User(id: 0);
568568
$this->assert_is_empty($user->to_representation()['password']);
569569
}
570+
571+
/**
572+
* Checks that the `override_sensitive_fields` field successfully overrides specified sensitive fields in the Model's
573+
* representation.
574+
*/
575+
public function test_override_sensitive_fields(): void {
576+
# Ignore the sensitive flag for the User model's password field
577+
$api_settings = new RESTAPISettings(override_sensitive_fields: ['User:password']);
578+
$api_settings->update();
579+
580+
# Ensure we can now read the password field in the User model's representation
581+
$user = new User(id: 0);
582+
$this->assert_is_not_empty($user->to_representation()['password']);
583+
584+
# Reset the override_sensitive_fields setting
585+
$api_settings = new RESTAPISettings(override_sensitive_fields: []);
586+
$api_settings->update();
587+
588+
# Ensure we can no longer read the password
589+
$user = new User(id: 0);
590+
$this->assert_is_empty($user->to_representation()['password']);
591+
}
570592
}

pfSense-pkg-RESTAPI/files/usr/local/share/pfSense-pkg-RESTAPI/info.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<log_successful_auth>disabled</log_successful_auth>
1818
<hateoas>disabled</hateoas>
1919
<expose_sensitive_fields>disabled</expose_sensitive_fields>
20+
<override_sensitive_fields></override_sensitive_fields>
2021
<allow_pre_releases>disabled</allow_pre_releases>
2122
<allowed_interfaces></allowed_interfaces>
2223
<represent_interfaces_as>id</represent_interfaces_as>

tools/make_package.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ def __init__(self):
3838
self.port_version = self.args.tag.split("_")[0]
3939
self.port_revision = self.args.tag.split("_", maxsplit=1)[1]
4040

41+
# Allow package to build on systems that no longer have upstream ports support
42+
os.environ["ALLOW_UNSUPPORTED_SYSTEM"] = "yes"
43+
4144
# Run tasks for build mode
4245
if self.args.host:
4346
self.build_on_remote_host()

0 commit comments

Comments
 (0)