Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
2879a22
- motp_enable optional now (#767)
vitspec99 Oct 25, 2025
720a38c
perf: setup simple caching for model classes
jaredhendrickson13 Nov 18, 2025
362009e
perf: clear object cache after any change
jaredhendrickson13 Nov 18, 2025
96f5e6f
perf(ForeignModelField): index in-scope model objects
jaredhendrickson13 Nov 18, 2025
85cddb6
perf(ForeignModelField): adjust foreign model indexing
jaredhendrickson13 Nov 21, 2025
91044c5
style: run prettier on changed files
jaredhendrickson13 Nov 21, 2025
15b8fd6
refactor: clear object cache on config modification, not model modifi…
jaredhendrickson13 Nov 22, 2025
01a0968
refactor: completely clear object cache on config change
jaredhendrickson13 Nov 22, 2025
63c2a09
revert: revert ForeignModelField changes
jaredhendrickson13 Nov 22, 2025
bfe0f2e
chore: use Model::set_config instead of config_set_path
jaredhendrickson13 Nov 22, 2025
772cdf6
fix: clear model object cache after test teardown
jaredhendrickson13 Nov 22, 2025
0d74bad
refactor: clear model cache on api crud methods
jaredhendrickson13 Nov 23, 2025
ab1ceeb
style: run prettier on changed files
jaredhendrickson13 Nov 23, 2025
c3a60d4
test: clean up restapi settings tests
jaredhendrickson13 Nov 23, 2025
391a4ee
fix: clear model object cache after package install
jaredhendrickson13 Nov 23, 2025
2e22e67
fix: exclude model's with parents from caching
jaredhendrickson13 Dec 4, 2025
4ae5c92
refactor: support queries on child models
jaredhendrickson13 Dec 6, 2025
17022aa
style: run prettier on changed files
jaredhendrickson13 Dec 6, 2025
35bac8a
fix: only load each parent model object once
jaredhendrickson13 Dec 7, 2025
3cf3733
fix: allow endpoints for child models to be many enabled
jaredhendrickson13 Dec 7, 2025
c33f888
refactor: prevent child model caching from clobbering from internal l…
jaredhendrickson13 Dec 9, 2025
af2d0e1
style: run prettier on changed files
jaredhendrickson13 Dec 9, 2025
2a62c8a
feat: implement model caching and indexing
jaredhendrickson13 Dec 14, 2025
74bbdf4
Merge branch 'master' of github.com:jaredhendrickson13/pfsense-api in…
jaredhendrickson13 Dec 14, 2025
d6805c7
test: ensure read_all() for child models contains objects from all pa…
jaredhendrickson13 Dec 14, 2025
e2effed
style: run prettier on changed files
jaredhendrickson13 Dec 14, 2025
f46a205
refactor: remove model indexing
jaredhendrickson13 Dec 16, 2025
fe83725
feat(QueryFilter): add query filter for finding objects whose field v…
jaredhendrickson13 Dec 16, 2025
1d15ead
docs: add docs page on security hardening
jaredhendrickson13 Dec 17, 2025
2d1eca4
perf: use caching and indexing to increase object relation performance
jaredhendrickson13 Dec 17, 2025
9b27398
style: run prettier on changed files
jaredhendrickson13 Dec 17, 2025
e707560
fix: allow indexing models with parents
jaredhendrickson13 Dec 17, 2025
33d3247
fix: make FirewallRule associated_rule_id unique field
jaredhendrickson13 Dec 17, 2025
8df0422
fix: make Service name unique field
jaredhendrickson13 Dec 17, 2025
e32be35
style: run prettier on changed files
jaredhendrickson13 Dec 17, 2025
013a718
revert: restore ability to index by id
jaredhendrickson13 Dec 17, 2025
d6a6d50
test: remove test that ensure child models couldn't be indexed
jaredhendrickson13 Dec 20, 2025
d14e54f
refactor!: require explicit creation of DHCPServer objects
jaredhendrickson13 Dec 20, 2025
6fd4f93
feat: add endpoints to allow querying child model objects #587
jaredhendrickson13 Dec 20, 2025
ed18245
feat: add missed endpoint for querying firewall schedule time ranges
jaredhendrickson13 Dec 21, 2025
0026d1e
docs: notate that basic auth is not inherently insecure
jaredhendrickson13 Dec 21, 2025
dfb4c25
chore: add return type hints to tests DHCPServer tests
jaredhendrickson13 Dec 21, 2025
841e490
test(DHCPServer): ensure DHCPServers can be created and deleted
jaredhendrickson13 Dec 21, 2025
53ad41f
docs: fix misordered list item
jaredhendrickson13 Dec 21, 2025
446fd65
test(DHCPServer): ensure interface is correctly created before crud t…
jaredhendrickson13 Jan 3, 2026
ff777ef
feat: finalize package logging facilities
jaredhendrickson13 Jan 3, 2026
f9123a8
chore: warn about installation on 32-bit systems
jaredhendrickson13 Jan 3, 2026
51d5efc
docs: adjust warning about 32-bit hardware in documentation
jaredhendrickson13 Jan 3, 2026
b4c35a4
Merge branch 'master' of github.com:jaredhendrickson13/pfsense-api in…
jaredhendrickson13 Jan 4, 2026
6fbc476
docs: remove arch specific mention from 32-bit warning
jaredhendrickson13 Jan 4, 2026
5e8000d
chore: typo/whitespace corrections
jaredhendrickson13 Jan 4, 2026
a45a75a
fix(PortForward): set disabled value during associated rule creation/…
jaredhendrickson13 Jan 4, 2026
3bfb6b1
perf: allow Model classes to be marked as ModelCache exempt
jaredhendrickson13 Jan 4, 2026
5ab8e56
feat: allow configurable log levels
jaredhendrickson13 Jan 4, 2026
80e4950
refactor: use string representation for log levels
jaredhendrickson13 Jan 7, 2026
62ca4fe
style: run prettier on changed files
jaredhendrickson13 Jan 7, 2026
0fe1596
feat: add POST /api/v2/diagnostics/ping endpoint (#820)
novastate Jan 7, 2026
2beb842
fix: do not cache models with internal callables by default
jaredhendrickson13 Jan 10, 2026
6aff549
refactor: remove redundant log_error method from Dispatcher class
jaredhendrickson13 Jan 10, 2026
3ba673f
Merge branch 'next_minor' of github.com:jaredhendrickson13/pfsense-ap…
jaredhendrickson13 Jan 10, 2026
e1cfc50
chore: only check log level once
jaredhendrickson13 Jan 10, 2026
747d61b
feat: add log_level field to RESTAPI Settings form page
jaredhendrickson13 Jan 10, 2026
c7f0b52
refactor: deprecate old log_error method
jaredhendrickson13 Jan 10, 2026
d10b325
style: run prettier on changed files
jaredhendrickson13 Jan 10, 2026
70029c8
feat: log security related events
jaredhendrickson13 Jan 10, 2026
5918c74
style: run prettier on changed files
jaredhendrickson13 Jan 10, 2026
79340d8
feat(UserGroup): allow updating groups with `system` scope #822
jaredhendrickson13 Jan 16, 2026
a7751d6
feat: add model, endpoint and tests for REST API logs
jaredhendrickson13 Jan 17, 2026
2aae2bd
test: adjust UserGroup model creation during tests
jaredhendrickson13 Jan 17, 2026
d061af4
test: fix case sensitivity in UserGroup query
jaredhendrickson13 Jan 17, 2026
6ed5ecf
test: load system exact UserGroup by id
jaredhendrickson13 Jan 17, 2026
869934e
fix(ForeignModelField): use index to find matches not queries
jaredhendrickson13 Jan 17, 2026
4021b0f
chore(UserGroup): bump 'member' items maximum to 2048
jaredhendrickson13 Jan 17, 2026
7e06fd1
test(UserGroup): ensure we can update and read large user groups with…
jaredhendrickson13 Jan 17, 2026
fa7b489
style: run prettier on changed files
jaredhendrickson13 Jan 17, 2026
4194563
fix: re-add unique constraint to RoutingGatewayStatus model
jaredhendrickson13 Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/INSTALL_AND_CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Overall, the REST API package is designed to be as lightweight as possible and s
run pfSense. It's recommended to follow Netgate's [minimum hardware requirements](https://docs.netgate.com/pfsense/en/latest/hardware/minimum-requirements.html).

!!! Warning
- The package is currently not compatible with 32-bit builds of pfSense. It is recommended to use the [legacy v1 package](https://github.com/jaredhendrickson13/pfsense-api/tree/legacy) for 32-bit systems.
- The package is currently not supported on 32-bit architectures like the Netgate 3100 (SG-3100).
- While the package should behave identically on 64-bit architectures other than amd64, automated testing only covers amd64
builds of pfSense CE. Support on other architectures is not guaranteed.

Expand Down
9 changes: 9 additions & 0 deletions docs/QUERIES_FILTERS_AND_SORTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ value array contains a given value for array fields.
- Name: `contains`
- Example: `https://pfsense.example.com/api/v2/examples?fieldname__contains=example`

### In (in)

Search for objects whose field value is within a given array of values (when the filter value is an array), or search
for objects whose field value is a substring of a given string (when the filter value is a string).
- Name: `in`
- Examples:
- `https://pfsense.example.com/api/v2/examples?fieldname__in=example`
- `https://pfsense.example.com/api/v2/examples?fieldname__in[]=example1&fieldname__in[]=example2`

### Less Than (lt)

Search for objects whose field value is less than a given integer.
Expand Down
141 changes: 141 additions & 0 deletions docs/SECURING_API_ACCESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Securing API Access

In the age of network automation, APIs on network appliances unlocks incredible efficiency and potential, but it also
can also create a high-stakes attack vector. Unlike standard web applications, a compromised firewall doesn't just leak
data; it can grant attackers administrative control over your network's perimeter, allowing them to rewrite traffic rules
and bypass your defenses entirely. The REST API package includes several built-in security features to help protect
API access and ensure that only authorized users and systems can interact with your pfSense instances.

## Step 1: Follow Netgate's Best Practices for Remote Access

If you need access to the pfSense REST API from outside your local network, it is critical that you follow Netgate's
[Allowing Remote Access to the GUI¶](https://docs.netgate.com/pfsense/en/latest/recipes/remote-firewall-administration.html)
guide to ensure that your pfSense instance is properly secured against unauthorized access. This includes:

- Enabling HTTPS for the web GUI to encrypt traffic between clients and the pfSense instance.
- Using a VPN to connect to your pfSense instance remotely, rather than exposing the web GUI directly to the internet.
- Configuring strong firewall rules to restrict access to the webConfigurator.

## Step 2: Choose an Appropriate Authentication Method

The authentication method you choose for API access will depend on your specific use case and security requirements
for your environment. The pfSense REST API package supports several different authentication methods, and allows
multiple methods to be enabled simultaneously. The three main authentication methods supported are:

### Basic Authentication (Local Database)

[Basic authentication](AUTHENTICATION_AND_AUTHORIZATION.md#basic-authentication-local-database) allows you to authenticate
with the same username and password you use to log into the pfSense web GUI. This method is the default authentication
method for the REST API package as it allows for out-of-the-box functionality without any additional configuration.
However, basic authentication is less secure than other methods and should only be used in trusted environments and
over secure connections (e.g., HTTPS or VPN).

**Pros**:

- Easy to set up and use.
- No additional configuration required.

**Cons**:

- Less secure than other methods.
- Credentials are sent with each request, increasing the risk of interception, especially if not using HTTPS.
- Credentials may also allow web GUI and/or SSH access, which may not be desirable for API-only users.

!!! Note
Basic authentication is not inherently insecure. In fact, with the proper user account management, strong passwords,
and secure transport (HTTPS), basic authentication can be just as secure as key-based authentication methods.


### JWT Authentication

[JWT authentication](AUTHENTICATION_AND_AUTHORIZATION.md#json-web-token-jwt-authentication) allows you to authenticate
using JSON Web Tokens. These are short-lived, digitially signed tokens that can be used to authenticate API requests without
sending a username and password with each request. JWT authentication is more secure than basic authentication and is
recommended for production environments who need session-based or short-lived authentication. This is especially useful
for front-end applications or scripts that need to make multiple API requests over a short period of time.

**Pros**:

- More secure than basic authentication.
- Tokens can be short-lived, reducing the risk of compromise.
- Tokens do not expose pfSense user credentials with each request.

**Cons**:

- Requires additional configuration to set up.
- Tokens need to be refreshed before they expire.

### Key Authentication

[Key authentication](AUTHENTICATION_AND_AUTHORIZATION.md#api-key-authentication) allows you to authenticate using
dedicated API keys. These keys are created specifically for API access and never require a username or password to
be sent with requests. Key authentication is the most secure method and is recommended for production environments
where security is a top priority. This method is especially useful for automated systems or services that need to
make API requests without human intervention.

**Pros**:

- Most secure authentication method.
- API keys can be easily revoked or rotated without affecting user accounts.
- Does not expose pfSense user credentials with requests.
- Supports configurable key-lengths and hashing algorithms for purpose-specific security needs.

**Cons**:

- Requires additional configuration to set up.
- API keys need to be securely stored and managed.

## Step 3: Use API-specific user accounts

Regardless of the authentication method you choose, the REST API package uses pfSense's built-in privilege system to
control access to API endpoints. This means that all credentials used for API access must belong to a pfSense user account
who has been granted the appropriate API privileges. Each endpoint has its own privileges for each HTTP method supported
by that endpoint. It is highly recommended that you create dedicated user accounts specifically for API access, rather
than using existing user accounts that may have broader access. This helps to limit the potential impact of a
compromised account and allows for better tracking of API activity. It is also highly recommended to follow the principle
of least privilege when assigning API privileges to user accounts. Only grant the minimum privileges necessary for the
intended use case.

!!! Warning
The `page-all` privilege grants unrestricted access to all API endpoints and methods. Avoid assigning this privilege
to user accounts unless absolutely necessary, as it significantly increases the risk of unauthorized access and
potential misuse of the API.

## Step 4: Restrict API access to specific interfaces

By default, the pfSense REST API package allows requests received on any interface IP to respond to API requests. However,
you can restrict the API to only respond to requests received on specific interfaces if desired. This can help limit the
exposure of the API to only trusted networks or systems beyond just setting firewall rules. To configure which
interfaces the API will respond to, navigate to `System` > `REST API` > `Settings` > `Allowed Interfaces` and select
the desired interfaces.

!!! Warning
This setting is not a replacement for proper firewall rules. This setting should be used in addition to firewall rules
to provide a layered approach to security. Ensure that you have proper firewall rules in place to restrict access to the API
to only trusted networks or systems, then ensure the API is configured to only respond on those same interfaces.

## Step 5: Configure API access lists

The REST API package includes an API access list feature that allows you to restrict API access based on source IP,
network, time-of-day, and/or user. This provides an additional layer of security by allowing you to define specific rules for who
can access the API, when they can access it, and from where. To configure API access lists, navigate to `System` > `REST API` >
`Access Lists` and create the desired access list rules. When designing your access list rules, consider the following best practices:

- Only allow IPs you trust and have a legitimate use case for accessing the API.
- Only allow the relevant users to access the API from their respective IPs or networks.
- If possible, configure and apply a schedule to apply to the access list rules to limit access to only when necessary.

!!! Warning
This access control list is not a replacement for proper firewall rules. This setting should be used in addition to
firewall rules to provide a layered approach to security. Ensure that you have proper firewall rules in place to
restrict access to the API to only trusted networks or systems, then use the access list to further restrict access
based on your specific requirements.

## Step 6: Update Regularly

Ensure that you are running the latest version of the pfSense REST API package to benefit from the latest security
patches and features. Regularly check for updates and apply them as soon as possible to minimize the risk of vulnerabilities.

!!! Tip
If you are using Prometheus for monitoring in your environment, consider using the [official pfREST Prometheus exporter](https://github.com/pfrest/pfsense_exporter)
to monitor for outdated pfSense REST API package versions across your fleet of pfSense instances!
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ nav:
- Working with HATEOAS: WORKING_WITH_HATEOAS.md
- Common Control Parameters: COMMON_CONTROL_PARAMETERS.md
- GraphQL: GRAPHQL.md
- Securing API Access: SECURING_API_ACCESS.md
- Limitations & FAQs: LIMITATIONS_AND_FAQS.md
- API Reference: https://pfrest.org/api-docs/
- Advanced Topics:
Expand Down
7 changes: 7 additions & 0 deletions pfSense-pkg-RESTAPI/files/pkg-install.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#!/bin/sh

if [ "${2}" != "POST-INSTALL" ]; then
exit 0
fi

# Warn users installing on 32-bit systems
ARCH_BITS=$(/usr/bin/getconf LONG_BIT)
if [ "${ARCH_BITS}" = "32" ]; then
echo "!!! WARNING: This package is not supported on 32-bit systems. !!!"
fi

# Make this package known to pfSense
/usr/local/bin/php -f /etc/rc.packages %%PORTNAME%% ${2}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ function delete(): void {
*/
function rotate_server_key(): void {
$pkg_index = RESTAPISettings::get_pkg_id();
config_set_path("installedpackages/package/$pkg_index/conf/keys", []);
Model::set_config("installedpackages/package/$pkg_index/conf/keys", []);
echo 'Rotating REST API server key... ';
RESTAPIJWT::init_server_key(rotate: true);
echo 'done.' . PHP_EOL;
Expand Down
4 changes: 4 additions & 0 deletions pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Core/Auth.inc
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ class Auth {
# If this Auth class is being requested by the remote client, set the matched auth and break the loop
if ($auth->is_requested()) {
$matched_auth = $auth;
self::log(
level: LOG_DEBUG,
message: "Client from $auth->ip_address is attempting to authenticate using $auth->verbose_name.",
);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
namespace RESTAPI\Core;

use ReflectionClass;
use RESTAPI\Models\RESTAPISettings;
use function RESTAPI\Core\Tools\get_classes_from_namespace;

/**
* Defines a standard set of traits for all classes defined by this package. When class use this trait they will
* automatically inherit all resources included.
*/
trait BaseTraits {
private static int $__log_level;

/**
* Obtains the shortname of the called class.
* @return string The shortname for this object's class.
*/
public function get_class_shortname(): string {
return (new ReflectionClass($this))->getShortName();
public static function get_class_shortname(): string {
return (new ReflectionClass(static::class))->getShortName();
}

/**
* Obtains the fully qualified name of the called class.
* @return string The FQN for this object's class.
*/
public function get_class_fqn(): string {
return (new ReflectionClass($this))->getName();
public static function get_class_fqn(): string {
return (new ReflectionClass(static::class))->getName();
}

/**
Expand All @@ -35,11 +38,32 @@ trait BaseTraits {
}

/**
* Logs an error to the syslog.
* @param string $message The error message to write to the syslog
* Writes a log entry to the applicable log file
* @param int $level The log level to write. This should be one of the LOG_* constants defined by syslog.
* @param string $message The message to write to the log file.
* @param string $logfile The log file to write to. This must be a valid logging facility defined in the package's
* info.xml file.
*/
public static function log_error(string $message): void {
# Call the pfSense `log_error` function
log_error($message);
public static function log(int $level, string $message, string $logfile = 'restapi'): void {
# If this is a system log, use the pfSense 'log_error' function instead
if ($logfile === 'system') {
log_error($message);
return;
}

# If the log level has not been set yet, obtain it
if (!isset(self::$__log_level)) {
self::$__log_level = constant(RESTAPISettings::get_pkg_config()['log_level']) ?? 4;
}

# Do not log if the incoming level is higher than the configured log level
if ($level > self::$__log_level) {
return;
}

# Otherwise, write to the applicable log file
openlog($logfile, flags: LOG_PID, facility: LOG_LOCAL0);
syslog(priority: $level, message: $message);
closelog();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,6 @@ class Dispatcher {
sleep(30);
}

/**
* Logs an error to the syslog.
* @param string $message The error message to write to the syslog
*/
public static function log_error(string $message): void {
# Call the pfSense `log_error` function
log_error($message);
}

/**
* Configures this Dispatcher to run on a schedule if the `schedule` property is set.
* @return CronJob|null Returns the CronJob created for this Dispatcher if a `schedule` is defined. Returns `null`
Expand Down
34 changes: 19 additions & 15 deletions pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Core/Endpoint.inc
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,6 @@ class Endpoint {
);
}
}

# Do not allow `many` Endpoints that are assigned a Model with a parent Model
if ($this->many and $this->model->parent_model_class) {
throw new ServerError(
message: 'Endpoints cannot enable `many` when the assigned Model has a parent Model',
response_id: 'ENDPOINT_MANY_WHEN_MODEL_HAS_PARENT',
);
}
}

/**
Expand Down Expand Up @@ -633,13 +625,19 @@ class Endpoint {
private function check_acl(): void {
# Allow the API call if the ignore_acl flag is set
if ($this->ignore_acl) {
$this->log(level: LOG_DEBUG, message: "Ignoring REST API ACL for $this->url as ignore_acl is set.");
return;
}

# Check if the client is allowed to access this Endpoint according to the REST API Access List
if (
!RESTAPIAccessListEntry::is_allowed_by_acl(ip: $this->client->ip_address, username: $this->client->username)
) {
$this->log(
level: LOG_WARNING,
message: "Denied {$this->client->username}@{$this->client->ip_address} access to $this->url for REST " .
'API access list violation.',
);
throw new ForbiddenError(
message: 'The requested action is not allowed by admin policy',
response_id: 'ENDPOINT_CLIENT_NOT_ALLOWED_BY_ACL',
Expand All @@ -651,7 +649,10 @@ class Endpoint {
* Checks if the API is enabled before allowing the call.
*/
private function check_enabled(): void {
$client_ip = $_SERVER['REMOTE_ADDR'];

if (!$this->restapi_settings->enabled->value and !$this->ignore_enabled) {
$this->log(level: LOG_WARNING, message: "Denied $client_ip access to $this->url as REST API is disabled.");
throw new ServiceUnavailableError(
message: 'The REST API is currently not enabled.',
response_id: 'ENDPOINT_REST_API_IS_NOT_ENABLED',
Expand All @@ -665,6 +666,7 @@ class Endpoint {
private function check_interface_allowed(): void {
# Variables
$server_ip = $_SERVER['SERVER_ADDR'];
$client_ip = $_SERVER['REMOTE_ADDR'];
$allowed_interfaces = $this->restapi_settings->allowed_interfaces->value;

# Allow any interface if the allowed interfaces is empty or the ignore_interfaces flag is set
Expand All @@ -678,25 +680,27 @@ class Endpoint {
}

# Loop through each allowed interface and check if the server IP is allowed to answer API calls
foreach (
$this->restapi_settings->allowed_interfaces->get_related_models()->model_objects
as $allowed_interface
) {
foreach ($this->restapi_settings->allowed_interfaces->get_related_models()->model_objects as $allowed_if) {
# Allow the server IP if it matches the current interface's IPv4 or IPv6 address
if ($server_ip === $allowed_interface->get_current_ipv4()) {
if ($server_ip === $allowed_if->get_current_ipv4()) {
return;
}
if ($server_ip === $allowed_interface->get_current_ipv6()) {
if ($server_ip === $allowed_if->get_current_ipv6()) {
return;
}

# Check if this interface has a virtual IP that matches the server IP that accepted the API call
$vip_q = VirtualIP::query(interface: $allowed_interface->represented_as(), subnet: $server_ip);
$vip_q = VirtualIP::query(interface: $allowed_if->represented_as(), subnet: $server_ip);
if ($vip_q->exists()) {
return;
}
}

# Throw a forbidden error if this API call was made to a non-API enabled interface
$this->log(
level: LOG_WARNING,
message: "Denied $client_ip access to $this->url as interface IP $server_ip is not allowed to respond.",
);
throw new ForbiddenError(
message: 'The requested action is not allowed by admin policy',
response_id: 'ENDPOINT_INTERFACE_NOT_ALLOWED',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ class Field {
}

# Use $modelset if provided. Otherwise, use all existing $context model objects as the $modelset
$modelset = $modelset ?: $this->context->read_all(parent_id: $this->context->parent_id);
$modelset = $modelset ?: $this->context->query(parent_id: $this->context->parent_id);

# If this is a $many field, query for any other object has this value in the array
if ($this->many) {
Expand Down
Loading