Skip to content

Commit 288a9a5

Browse files
Merge pull request #120 from jaredhendrickson13/v122_fixes
v1.2.2 Fixes & Features
2 parents 57f123d + 1fded07 commit 288a9a5

13 files changed

Lines changed: 10394 additions & 9050 deletions

File tree

docs/CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ to `tools/README.md`
529529

530530
## Creating or Updating Documentation ##
531531
Documentation is written and maintained using Postman. The JSON export of the Postman collection can be found in
532-
`docs/documentation.json`. Both the README.md and embedded documentation are generated using this JSON file. To update
532+
`tools/templates/documentation.json`. Both the README.md and embedded documentation are generated using this JSON file. To update
533533
or add documentation, you can either import this collection to Postman, make your changes in Postman and then export the
534534
updated collection as JSON, or you may edit the JSON file directly if you are familiar with the structure. To generate
535535
the README.md and embedded documentation pages, you may use the `tools/make_documentation.py` script. For more info on
@@ -538,4 +538,4 @@ running the script, refer to `tools/README.md`
538538
Questions
539539
---------
540540
There are some complex components to this project. Please feel free to reach out with any questions,
541-
issues, or insight you have when creating API endpoints. Time permitting I am happy to help any way I can.
541+
issues, or insight you have when creating API endpoints. Time permitting I am happy to help any way I can.

docs/documentation.json

Lines changed: 0 additions & 8998 deletions
This file was deleted.

pfSense-pkg-API/files/etc/inc/api/framework/APITools.inc

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ function sort_nat_rules($top=false, $data=null, $field=null) {
315315
}
316316

317317
# Input a physical interface ID, or a descriptive interface name, and return the pfSense interface ID (lan,wan,optx)
318-
function get_pfsense_if_id($interface) {
318+
function get_pfsense_if_id($interface, $include_carp=false) {
319319
# Variables
320320
global $config;
321321
# Loop through our config and check each interface for a physical ID match
@@ -342,18 +342,19 @@ function get_pfsense_if_id($interface) {
342342
if ($interface === $if_id) {
343343
return $if_id;
344344
}
345-
346345
}
347346

348-
# Loop on carp _vip interfaces
349-
foreach ($config['virtualip']['vip'] as $carp) {
350-
if ($carp['mode'] == "carp") {
351-
if ($interface === '_vip'.$carp['uniqid']) {
352-
return $interface;
347+
# Only include CARP interfaces if they are explicitly requested
348+
if ($include_carp) {
349+
# Loop on carp _vip interfaces
350+
foreach ($config['virtualip']['vip'] as $carp) {
351+
if ($carp['mode'] == "carp") {
352+
if ($interface === '_vip'.$carp['uniqid']) {
353+
return $interface;
354+
}
353355
}
354356
}
355357
}
356-
357358
}
358359

359360
# Check if input is valid for rule source and destination

pfSense-pkg-API/files/etc/inc/api/models/APIFirewallVirtualIPCreate.inc

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,22 @@ class APIFirewallVirtualIPCreate extends APIModel {
3737
}
3838

3939
public function validate_payload() {
40+
# Assign a unique ID to the virtual IP
41+
$this->validated_data['uniqid'] = uniqid();
42+
43+
# Validate input data
44+
$this->__validate_mode();
45+
$this->__validate_interface();
46+
$this->__validate_subnet();
47+
$this->__validate_descr();
48+
$this->__validate_noexpand();
49+
$this->__validate_vhid();
50+
$this->__validate_advbase();
51+
$this->__validate_advskew();
52+
$this->__validate_password();
53+
}
4054

55+
private function __validate_mode() {
4156
# Validate our required 'mode' payload value
4257
if (isset($this->initial_data['mode'])) {
4358
$mode_options = array("ipalias", "carp", "proxyarp", "other");
@@ -49,11 +64,13 @@ class APIFirewallVirtualIPCreate extends APIModel {
4964
} else {
5065
$this->errors[] = APIResponse\get(4019);
5166
}
67+
}
5268

69+
private function __validate_interface() {
5370
# Validate our required 'interface' payload value
5471
if (isset($this->initial_data['interface'])) {
5572
# Convert this interface into the pfSense interface ID or set error if not found
56-
$this->initial_data["interface"] = APITools\get_pfsense_if_id($this->initial_data["interface"]);
73+
$this->initial_data["interface"] = APITools\get_pfsense_if_id($this->initial_data["interface"], true);
5774
if (is_string($this->initial_data["interface"])) {
5875
$this->validated_data["interface"] = $this->initial_data["interface"];
5976
} else {
@@ -62,7 +79,9 @@ class APIFirewallVirtualIPCreate extends APIModel {
6279
} else {
6380
$this->errors[] = APIResponse\get(4020);
6481
}
82+
}
6583

84+
private function __validate_subnet() {
6685
# Validate our required 'subnet' payload value
6786
if (isset($this->initial_data['subnet'])) {
6887
// If a single IPv4 or IPv6, append the subnet mask for one address
@@ -80,31 +99,45 @@ class APIFirewallVirtualIPCreate extends APIModel {
8099
} else {
81100
$this->validated_data["subnet"] = $subnet_split[0];
82101
$this->validated_data["subnet_bits"] = $subnet_split[1];
102+
103+
# Set virtual IP type to network/single based on subnet and subnet_bits
104+
if (is_ipaddrv4($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 32) {
105+
$this->validated_data["type"] = "single";
106+
} elseif (is_ipaddrv6($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 128) {
107+
$this->validated_data["type"] = "single";
108+
} else {
109+
$this->validated_data["type"] = "network";
110+
}
83111
}
84112
} else {
85113
$this->errors[] = APIResponse\get(4025);
86114
}
87-
88115
} else {
89116
$this->errors[] = APIResponse\get(4021);
90117
}
118+
}
91119

92-
# Validate our required 'descr' payload value
120+
private function __validate_descr() {
121+
# Validate our optional 'descr' payload value
93122
if (isset($this->initial_data['descr'])) {
94123
$this->validated_data["descr"] = strval($this->initial_data['descr']);
95124
} else {
96125
$this->validated_data["descr"] = "";
97126
}
127+
}
98128

99-
# Validate our required 'noexpand' payload value
129+
private function __validate_noexpand() {
130+
# Validate our optional 'noexpand' payload value
100131
if ($this->initial_data['noexpand'] === true and in_array($this->initial_data["mode"], ["proxyarp", "other"])) {
101132
$this->validated_data['noexpand'] = "";
102133
}
134+
}
103135

104-
# Validate CARP conditional payload values
136+
private function __validate_vhid() {
137+
# Only validate this field if the mode was set to CARP
105138
if ($this->validated_data["mode"] === "carp") {
106139
# Check for our optional 'vhid' payload value. Assume default if none was specified.
107-
if (isset($this->initial_data['vhid'])) {
140+
if (isset($this->initial_data['vhid']) ) {
108141
if ($this->__vhid_exists($this->initial_data["interface"], $this->initial_data['vhid'])) {
109142
$this->errors[] = APIResponse\get(4027);
110143
} elseif (1 > $this->initial_data['vhid'] or $this->initial_data['vhid'] > 255) {
@@ -116,7 +149,12 @@ class APIFirewallVirtualIPCreate extends APIModel {
116149
# If a VHID was not specified, use the next available VHID
117150
$this->validated_data["vhid"] = APITools\next_vhid();
118151
}
152+
}
153+
}
119154

155+
private function __validate_advskew() {
156+
# Only validate this field if the mode was set to CARP
157+
if ($this->validated_data["mode"] === "carp") {
120158
# Check for our optional 'advskew' payload value. Assume default if none was specified.
121159
if (isset($this->initial_data['advskew'])) {
122160
# Ensure 'advskew' value is within range
@@ -128,7 +166,12 @@ class APIFirewallVirtualIPCreate extends APIModel {
128166
} else {
129167
$this->validated_data["advskew"] = 0;
130168
}
169+
}
170+
}
131171

172+
private function __validate_advbase() {
173+
# Only validate this field if the mode was set to CARP
174+
if ($this->validated_data["mode"] === "carp") {
132175
# Check for our optional 'advbase' payload value. Assume default if none was specified.
133176
if (isset($this->initial_data['advbase'])) {
134177
# Ensure 'advbase' value is within range
@@ -140,23 +183,19 @@ class APIFirewallVirtualIPCreate extends APIModel {
140183
} else {
141184
$this->validated_data["advbase"] = 1;
142185
}
186+
}
187+
}
143188

144-
# Check for our require 'password' payload value. Set error if none was specified.
189+
private function __validate_password() {
190+
# Only validate this field if the mode was set to CARP
191+
if ($this->validated_data["mode"] === "carp") {
192+
# Check for the required 'password' payload value. Set error if none was specified.
145193
if (isset($this->initial_data['password'])) {
146194
$this->validated_data["password"] = strval($this->initial_data['password']);
147195
} else {
148196
$this->errors[] = APIResponse\get(4022);
149197
}
150198
}
151-
152-
# Set virtual IP type to network/single based on subnet and subnet_bits
153-
if (is_ipaddrv4($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 32) {
154-
$this->validated_data["type"] = "single";
155-
} elseif (is_ipaddrv6($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 128) {
156-
$this->validated_data["type"] = "single";
157-
} else {
158-
$this->validated_data["type"] = "network";
159-
}
160199
}
161200

162201
private function __vhid_exists($interface, $vhid) {
@@ -168,5 +207,4 @@ class APIFirewallVirtualIPCreate extends APIModel {
168207
}
169208
return false;
170209
}
171-
172210
}

pfSense-pkg-API/files/etc/inc/api/models/APIFirewallVirtualIPUpdate.inc

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ require_once("api/framework/APIModel.inc");
1717
require_once("api/framework/APIResponse.inc");
1818

1919
class APIFirewallVirtualIPUpdate extends APIModel {
20+
private $__prev_mode;
21+
2022
# Create our method constructor
2123
public function __construct() {
2224
parent::__construct();
@@ -33,6 +35,19 @@ class APIFirewallVirtualIPUpdate extends APIModel {
3335
}
3436

3537
public function validate_payload() {
38+
$this->__validate_id();
39+
$this->__validate_mode();
40+
$this->__validate_interface();
41+
$this->__validate_subnet();
42+
$this->__validate_descr();
43+
$this->__validate_noexpand();
44+
$this->__validate_vhid();
45+
$this->__validate_advbase();
46+
$this->__validate_advskew();
47+
$this->__validate_password();
48+
}
49+
50+
private function __validate_id() {
3651
# Validate our required 'id' payload value
3752
if (isset($this->initial_data['id'])) {
3853
# Check that our rule ID exists
@@ -45,29 +60,35 @@ class APIFirewallVirtualIPUpdate extends APIModel {
4560
} else {
4661
$this->errors[] = APIResponse\get(4017);
4762
}
63+
}
4864

65+
private function __validate_mode() {
4966
# Validate our optional 'mode' payload value
5067
if (isset($this->initial_data['mode'])) {
5168
$mode_options = array("ipalias", "carp", "proxyarp", "other");
5269
if (in_array($this->initial_data['mode'], $mode_options)) {
53-
$previous_mode = $this->validated_data["mode"];
70+
$this->__prev_mode = $this->validated_data["mode"];
5471
$this->validated_data["mode"] = $this->initial_data['mode'];
5572
} else {
5673
$this->errors[] = APIResponse\get(4023);
5774
}
5875
}
76+
}
5977

78+
private function __validate_interface() {
6079
# Validate our optional 'interface' payload value
6180
if (isset($this->initial_data['interface'])) {
6281
# Convert this interface into the pfSense interface ID or set error if not found
63-
$this->initial_data["interface"] = APITools\get_pfsense_if_id($this->initial_data["interface"]);
82+
$this->initial_data["interface"] = APITools\get_pfsense_if_id($this->initial_data["interface"], true);
6483
if (is_string($this->initial_data["interface"])) {
6584
$this->validated_data["interface"] = $this->initial_data["interface"];
6685
} else {
6786
$this->errors[] = APIResponse\get(4024);
6887
}
6988
}
89+
}
7090

91+
private function __validate_subnet() {
7192
# Validate our optional 'subnet' payload value
7293
if (isset($this->initial_data['subnet'])) {
7394
// If a single IPv4 or IPv6, append the subnet mask for one address
@@ -85,23 +106,38 @@ class APIFirewallVirtualIPUpdate extends APIModel {
85106
} else {
86107
$this->validated_data["subnet"] = $subnet_split[0];
87108
$this->validated_data["subnet_bits"] = $subnet_split[1];
109+
110+
# Set virtual IP type to network/single based on subnet and subnet_bits
111+
if (is_ipaddrv4($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 32) {
112+
$this->validated_data["type"] = "single";
113+
} elseif (is_ipaddrv6($this->validated_data["subnet"]) && $this->validated_data["subnet_bits"] == 128) {
114+
$this->validated_data["type"] = "single";
115+
} else {
116+
$this->validated_data["type"] = "network";
117+
}
88118
}
89119
} else {
90120
$this->errors[] = APIResponse\get(4025);
91121
}
92122
}
123+
}
93124

125+
private function __validate_descr() {
94126
# Validate our optional 'descr' payload value
95127
if (isset($this->initial_data['descr'])) {
96128
$this->validated_data["descr"] = strval($this->initial_data['descr']);
97129
}
130+
}
98131

132+
private function __validate_noexpand() {
99133
# Validate our optional 'noexpand' payload value
100134
if ($this->initial_data['noexpand'] === true and in_array($this->initial_data["mode"], ["proxyarp", "other"])) {
101135
$this->validated_data['noexpand'] = "";
102136
}
137+
}
103138

104-
# Validate CARP conditional payload values
139+
private function __validate_vhid() {
140+
# Only validate this field if the mode is set to CARP
105141
if ($this->validated_data["mode"] === "carp") {
106142
# Check for our optional 'vhid' payload value. Assume default if none was specified.
107143
if (isset($this->initial_data['vhid'])) {
@@ -112,11 +148,16 @@ class APIFirewallVirtualIPUpdate extends APIModel {
112148
} else {
113149
$this->validated_data["vhid"] = $this->initial_data["vhid"];
114150
}
115-
} elseif ($previous_mode !== "carp") {
151+
} elseif ($this->__prev_mode !== "carp") {
116152
# If a VHID was not specified, use the next available VHID
117153
$this->validated_data["vhid"] = APITools\next_vhid();
118154
}
155+
}
156+
}
119157

158+
private function __validate_advskew() {
159+
# Only validate this field if the mode is set to CARP
160+
if ($this->validated_data["mode"] === "carp") {
120161
# Check for our optional 'advskew' payload value. Assume default if none was specified.
121162
if (isset($this->initial_data['advskew'])) {
122163
# Ensure 'advskew' value is within range
@@ -125,10 +166,15 @@ class APIFirewallVirtualIPUpdate extends APIModel {
125166
} else {
126167
$this->validated_data["advskew"] = intval($this->initial_data['advskew']);
127168
}
128-
} elseif ($previous_mode !== "carp") {
169+
} elseif ($this->__prev_mode !== "carp") {
129170
$this->validated_data["advskew"] = 0;
130171
}
172+
}
173+
}
131174

175+
private function __validate_advbase() {
176+
# Only validate this field if the mode is set to CARP
177+
if ($this->validated_data["mode"] === "carp") {
132178
# Check for our optional 'advbase' payload value. Assume default if none was specified.
133179
if (isset($this->initial_data['advbase'])) {
134180
# Ensure 'advbase' value is within range
@@ -137,20 +183,22 @@ class APIFirewallVirtualIPUpdate extends APIModel {
137183
} else {
138184
$this->validated_data["advbase"] = intval($this->initial_data['advbase']);
139185
}
140-
} elseif ($previous_mode !== "carp") {
186+
} elseif ($this->__prev_mode !== "carp") {
141187
$this->validated_data["advbase"] = 1;
142188
}
189+
}
190+
}
143191

192+
private function __validate_password() {
193+
# Validate CARP conditional payload values
194+
if ($this->validated_data["mode"] === "carp") {
144195
# Check for our require 'password' payload value. Set error if none was specified.
145196
if (isset($this->initial_data['password'])) {
146197
$this->validated_data["password"] = strval($this->initial_data['password']);
147-
} elseif ($previous_mode !== "carp") {
198+
} elseif ($this->__prev_mode !== "carp") {
148199
$this->errors[] = APIResponse\get(4022);
149200
}
150201
}
151-
152-
# Set virtual IP type to network. This is easier to handle than allow single IPs too.
153-
$this->validated_data["type"] = "network";
154202
}
155203

156204
private function __vhid_exists($vhid) {
@@ -162,4 +210,4 @@ class APIFirewallVirtualIPUpdate extends APIModel {
162210
}
163211
return false;
164212
}
165-
}
213+
}

pfSense-pkg-API/files/usr/local/www/api/documentation/index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1983,7 +1983,7 @@
19831983
function IsJsonString(str){try{JSON.parse(str);}catch(e){return false;}
19841984
return true;}
19851985
String.prototype.replaceAll=function(replaceThis,withThis){var re=new RegExp(RegExp.quote(replaceThis),"g");return this.replace(re,withThis);};RegExp.quote=function(str){return str.replace(/([.?*+^$[\]\\(){}-])/g,"\\$1");};function syntaxHighlight(json){json=json.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,function(match){var cls='number';if(/^"/.test(match)){if(/:$/.test(match)){cls='key';}else{cls='string';}}else if(/true|false/.test(match)){cls='boolean';}else if(/null/.test(match)){cls='null';}
1986-
return '<span class="'+cls+'">'+match+'</span>';});}</script><br><br><footer class="navbar-default navbar-fixed-bottom"><div class=container-fluid><div class="span12 text-center"><span data-toggle=tooltip title="If the application help you, please feel free to give a star to the project in github. Your star inspire me to work more on open-source projects like this!">Made with <em class=love-color>&#9829;</em> by <a href=https://github.com/thedevsaddam target=_blank class=text-muted>thedevsaddam</a> | Generated at: 2021-03-22 21:57:19 by <a href=https://github.com/thedevsaddam/docgen target=_blank class=text-muted>docgen</a></span></div></div></footer>
1986+
return '<span class="'+cls+'">'+match+'</span>';});}</script><br><br><footer class="navbar-default navbar-fixed-bottom"><div class=container-fluid><div class="span12 text-center"><span data-toggle=tooltip title="If the application help you, please feel free to give a star to the project in github. Your star inspire me to work more on open-source projects like this!">Made with <em class=love-color>&#9829;</em> by <a href=https://github.com/thedevsaddam target=_blank class=text-muted>thedevsaddam</a> | Generated at: 2021-04-05 09:37:25 by <a href=https://github.com/thedevsaddam/docgen target=_blank class=text-muted>docgen</a></span></div></div></footer>
19871987
<script type="text/javascript">
19881988
$(document).ready(function() {
19891989
document.title = 'pfSense REST API Documentation';

0 commit comments

Comments
 (0)