Skip to content

Commit 15ab63c

Browse files
chore(FreeRADIUSClient): cleanup FreeRADIUSClient model
1 parent 67c5404 commit 15ab63c

1 file changed

Lines changed: 77 additions & 68 deletions

File tree

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

Lines changed: 77 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,83 +5,77 @@ namespace RESTAPI\Models;
55
require_once 'RESTAPI/autoloader.inc';
66

77
use RESTAPI\Core\Model;
8-
use RESTAPI\Fields\Base64Field;
98
use RESTAPI\Fields\BooleanField;
10-
use RESTAPI\Fields\ForeignModelField;
119
use RESTAPI\Fields\IntegerField;
1210
use RESTAPI\Fields\PortField;
13-
use RESTAPI\Fields\ObjectField;
1411
use RESTAPI\Fields\StringField;
15-
use RESTAPI\Responses\ConflictError;
1612
use RESTAPI\Responses\ValidationError;
17-
use RESTAPI\Responses\ServerError;
18-
use RESTAPI\Validators\HostnameValidator;
1913
use RESTAPI\Validators\IPAddressValidator;
2014
use RESTAPI\Validators\RegexValidator;
2115

2216
/**
23-
* Defines a Model that represents FreeRADIUS Interfaces
17+
* Defines a Model that represents FreeRADIUS Clients
2418
*/
2519
class FreeRADIUSClient extends Model {
2620
public StringField $addr;
2721
public PortField $port;
2822
public StringField $type;
29-
public StringField $ipv;
23+
public StringField $ip_version;
3024
public StringField $description;
25+
public StringField $shortname;
26+
public StringField $secret;
27+
public StringField $proto;
28+
public StringField $nastype;
29+
public BooleanField $msgauth;
30+
public IntegerField $maxconn;
31+
public StringField $naslogin;
32+
public StringField $naspassword;
3133

32-
/**
33-
*
34-
*/
3534
public function __construct(mixed $id = null, mixed $parent_id = null, mixed $data = [], mixed ...$options) {
36-
#
3735
# Set model attributes
38-
#
3936
$this->packages = ['pfSense-pkg-freeradius3'];
4037
$this->package_includes = ['freeradius.inc'];
4138
$this->config_path = 'installedpackages/freeradiusclients/config';
4239
$this->many = true;
4340
$this->always_apply = true;
4441

45-
#
4642
# Set model fields
47-
#
4843
$this->addr = new StringField(
49-
internal_name: 'varclientip',
5044
required: true,
5145
unique: true,
46+
internal_name: 'varclientip',
5247
validators: [new IPAddressValidator(allow_ipv4: true, allow_ipv6: true)],
53-
help_text: 'The IP address or network of the RADIUS client(s) in CIDR notation. This is the IP of the NAS (switch, access point, firewall, router, etc.)',
48+
help_text: 'The IP address or network of the RADIUS client(s) in CIDR notation. This is the IP of the ' .
49+
'NAS (switch, access point, firewall, router, etc.)',
5450
);
55-
$this->ipv = new StringField(
56-
internal_name: 'varclientipversion',
57-
choices: ['ipaddr', 'ipv6addr'],
58-
allow_empty: true,
51+
$this->ip_version = new StringField(
5952
default: 'ipaddr',
53+
choices: ['ipaddr', 'ipv6addr'],
54+
internal_name: 'varclientipversion',
6055
help_text: 'The IP version of the this Client.',
6156
);
6257
$this->shortname = new StringField(
63-
internal_name: 'varclientshortname',
6458
required: true,
65-
allow_null: false,
59+
internal_name: 'varclientshortname',
6660
help_text: 'A short name for the client. This is generally the hostname of the NAS.',
6761
);
6862
$this->secret = new StringField(
69-
internal_name: 'varclientsharedsecret',
7063
required: true,
7164
sensitive: true,
72-
allow_empty: false,
73-
help_text: 'This is the shared secret (password) which the NAS (switch, accesspoint, etc.) needs to communicate with the RADIUS server.',
65+
maximum_length: 31,
66+
internal_name: 'varclientsharedsecret',
67+
help_text: 'This is the shared secret (password) which the NAS (switch, accesspoint, etc.) needs to ' .
68+
'communicate with the RADIUS server.',
7469
);
7570

7671
$this->proto = new StringField(
77-
internal_name: 'varclientproto',
78-
choices: ['udp', 'tcp'],
79-
allow_empty: true,
8072
default: 'udp',
81-
help_text: 'The protocol the client uses. (Default: udp)',
73+
choices: ['udp', 'tcp'],
74+
internal_name: 'varclientproto',
75+
help_text: 'The protocol the client uses.',
8276
);
8377
$this->nastype = new StringField(
84-
internal_name: 'varclientnastype',
78+
default: 'other',
8579
choices: [
8680
'cisco',
8781
'cvx',
@@ -96,41 +90,45 @@ class FreeRADIUSClient extends Model {
9690
'other',
9791
],
9892
allow_empty: true,
99-
default: 'other',
100-
help_text: 'The NAS type of the client. This is used by checkrad.pl for simultaneous use checks. (Default: other)',
93+
internal_name: 'varclientnastype',
94+
help_text: 'The NAS type of the client. This is used by checkrad.pl for simultaneous use checks.',
10195
);
102-
$this->msgauth = new StringField(
96+
$this->msgauth = new BooleanField(
97+
default: false,
98+
indicates_true: 'yes',
99+
indicates_false: 'no',
103100
internal_name: 'varrequiremessageauthenticator',
104-
choices: ['yes', 'no'],
105-
default: 'no',
106-
help_text: 'RFC5080 requires Message-Authenticator in Access-Request. But older NAS (switches or accesspoints) do not include that. (Default: no)',
101+
help_text: 'RFC5080 requires Message-Authenticator in Access-Request. But older NAS (switches or ' .
102+
'accesspoints) do not include that.',
107103
);
108104
$this->maxconn = new IntegerField(
109-
internal_name: 'varclientmaxconnections',
105+
default: 16,
110106
minimum: 1,
111107
maximum: 32,
112-
default: 16,
113-
help_text: 'Takes only effect if you use TCP as protocol. Limits the number of simultaneous TCP connections from a client. (max=32)',
108+
internal_name: 'varclientmaxconnections',
109+
help_text: 'Takes only effect if you use TCP as protocol. Limits the number of simultaneous TCP
110+
connections from a client.',
114111
);
115112
$this->naslogin = new StringField(
116-
internal_name: 'varclientlogininput',
117-
allow_empty: true,
118113
default: '',
119-
help_text: 'If supported by your NAS, you can use SNMP or finger for simultaneous-use checks instead of (s)radutmp file and accounting. Leave empty to choose (s)radutmp. (Default: empty) ',
114+
allow_empty: true,
115+
internal_name: 'varclientlogininput',
116+
help_text: 'If supported by your NAS, you can use SNMP or finger for simultaneous-use checks instead of ' .
117+
'(s)radutmp file and accounting. Leave empty to choose (s)radutmp.',
120118
);
121119
$this->naspassword = new StringField(
122-
internal_name: 'varclientpasswordinput',
123-
allow_empty: true,
124120
default: '',
121+
allow_empty: true,
125122
sensitive: true,
126-
help_text: 'If supported by your NAS, you can use SNMP or finger for simultaneous-use checks instead of (s)radutmp file and accounting. Leave empty to choose
127-
(s)radutmp. (Default: empty) ',
123+
internal_name: 'varclientpasswordinput',
124+
help_text: 'If supported by your NAS, you can use SNMP or finger for simultaneous-use checks instead of ' .
125+
'(s)radutmp file and accounting. Leave empty to choose (s)radutmp.',
128126
);
129127

130128
$this->description = new StringField(
131129
required: false,
132-
allow_empty: true,
133130
default: '',
131+
allow_empty: true,
134132
validators: [
135133
new RegexValidator(
136134
pattern: "/^[a-zA-Z0-9 _,.;:+=()-]*$/",
@@ -144,44 +142,55 @@ class FreeRADIUSClient extends Model {
144142
}
145143

146144
/**
147-
* Perform additional validation on the Model's fields and data.
145+
* Perform extra validation on the Model's 'addr' field.
146+
* @param string $value The value to validate.
147+
* @returns string The validated value.
148+
* @throws ValidationError If the value does not match IP version specified in the 'ip_version' field.
148149
*/
149-
public function validate_extra(): void {
150-
$input_errors = [];
150+
public function validate_addr(string $value): string {
151+
# Do not allow the value to be an IPv4 address if ip_version is 'ipv6addr'
152+
if ($this->addr->has_label('is_ipaddrv4') and $this->ip_version->value === 'ipv6addr') {
153+
throw new ValidationError(
154+
message: "Field `addr` cannot be an IPv4 address when `ip_version` is set to `ipv6addr`, received `$value`.",
155+
response_id: 'FREERADIUS_CLIENT_ADDR_IPV4_NOT_ALLOWED',
156+
);
157+
}
151158

152-
/*
153-
*/
154-
$iface_addr = $this->addr->value;
155-
if ($iface_addr != '*') {
156-
if (is_ipaddrv4($iface_addr)) {
157-
$this->ipv->value = 'ipaddr';
158-
} elseif (is_ipaddrv6($iface_addr)) {
159-
$this->ipv->value = 'ipv6addr';
160-
} else {
161-
// we don't must be here because Model validator for $this->addr
162-
$input_errors[] = "Cann't recognize IP-address={$iface_addr}";
163-
}
159+
# Do not allow the value to be an IPv6 address if ip_version is 'ipaddr'
160+
if ($this->addr->has_label('is_ipaddrv6') and $this->ip_version->value === 'ipaddr') {
161+
throw new ValidationError(
162+
message: "Field `addr` cannot be an IPv6 address when `ip_version` is set to `ipaddr`, received `$value`.",
163+
response_id: 'FREERADIUS_CLIENT_ADDR_IPV6_NOT_ALLOWED',
164+
);
164165
}
165166

166-
# Run service level validations
167-
$client = $this->to_internal();
168-
freeradius_validate_clients($iface, $input_errors);
167+
return $value;
168+
}
169169

170+
/**
171+
* Perform additional validation on the Model's fields and data.
172+
*/
173+
/**
174+
* Perform additional validation on the Model's fields and data.
175+
*/
176+
public function validate_extra(): void {
170177
# If there were validation errors that were not caught by the model fields, throw a ValidationError.
171178
# Ideally the Model should catch all validation errors itself so prompt the user to report this error
179+
$input_errors = [];
180+
freeradius_validate_clients($this->to_internal(), $input_errors);
172181
if (!empty($input_errors)) {
173182
throw new ValidationError(
174183
message: "An unexpected validation error has occurred: $input_errors[0]. Please report this issue at " .
175184
'https://github.com/jaredhendrickson13/pfsense-api/issues/new',
176-
response_id: 'FREERADIUS_USER_UNEXPECTED_VALIDATION_ERROR',
185+
response_id: 'FREERADIUS_CLIENTS_UNEXPECTED_VALIDATION_ERROR',
177186
);
178187
}
179188
}
180189

181190
/**
182191
* Apply specific action on Client(s)
183192
*/
184-
public function apply() {
193+
public function apply(): void {
185194
freeradius_clients_resync();
186195
}
187196
}

0 commit comments

Comments
 (0)