Skip to content

Commit 8fa65eb

Browse files
Restructured APIUserUpdateModel to fix #95 bug that prevent password from being set
1 parent 319b3e0 commit 8fa65eb

2 files changed

Lines changed: 102 additions & 26 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class APIUserCreate extends APIModel {
126126
private function __validate_authorizedkeys() {
127127
# Check for our optional `authorizedkeys` payload value
128128
if (isset($this->initial_data['authorizedkeys'])) {
129-
$this->validated_data["authorizedkeys"] = $this->initial_data['authorizedkeys'];
129+
$this->validated_data["authorizedkeys"] = base64_encode($this->initial_data['authorizedkeys']);
130130
}
131131
}
132132

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

Lines changed: 101 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,52 +25,128 @@ class APIUserUpdate extends APIModel {
2525
}
2626

2727
public function action() {
28-
local_user_set($this->validated_data);
28+
# Update our new user in the config and set the user on the backend
29+
$this->config["system"]["user"][$this->id] = $this->validated_data;
2930
$this->write_config();
31+
local_user_set($this->validated_data);
3032
return APIResponse\get(0, $this->validated_data);
3133
}
3234

33-
public function validate_payload() {
35+
private function __validate_username() {
36+
# Check for our required `username` payload value
3437
if (isset($this->initial_data['username'])) {
35-
$this->validated_data =& getUserEntry($this->initial_data['username']);
36-
// Check that our user already exists
37-
if (!array_key_exists("uid", $this->validated_data)) {
38+
# Loop through each configured user and check if this user exists
39+
foreach ($this->config["system"]["user"] as $id=>$user) {
40+
if ($this->initial_data["username"] === $user["name"]) {
41+
$this->validated_data = $user;
42+
$this->id = intval($id);
43+
}
44+
}
45+
# Set an error if no user was found
46+
if (!isset($this->validated_data["uid"])) {
3847
$this->errors[] = APIResponse\get(5001);
3948
}
4049
} else {
4150
$this->errors[] = APIResponse\get(5000);
4251
}
52+
}
53+
54+
private function __validate_password() {
55+
# Check for our optional `password` payload value
4356
if (isset($this->initial_data['password'])) {
44-
$password = $this->initial_data['password'];
45-
$password = trim($password);
46-
local_user_set_password($this->validated_data, $password); // Set our new user's password
57+
# Generate the password hash and add it to our validated data
58+
local_user_set_password($this->validated_data, $this->initial_data['password']);
4759
}
48-
if ($this->initial_data["disabled"] === true) {
49-
$this->validated_data["disabled"] = ""; // Update our user's disabled value if not false
50-
} elseif ($this->initial_data["disabled"] === false) {
51-
unset($this->validated_data["disabled"]); // Unset our disabled value if not requested
60+
}
5261

62+
private function __validate_priv() {
63+
global $priv_list;
64+
65+
# Check for our optional `priv` payload value
66+
if ($this->initial_data["priv"]) {
67+
# Revert priv array to default
68+
$this->validated_data["priv"] = [];
69+
70+
# Ensure value is an array
71+
if (!is_array($this->initial_data["priv"])) {
72+
$this->initial_data["priv"] = array($this->initial_data["priv"]);
73+
}
74+
75+
# Loop through each requested privilege and ensure it exists
76+
foreach ($this->initial_data["priv"] as $priv) {
77+
if (array_key_exists($priv, $priv_list)) {
78+
$this->validated_data["priv"][] = $priv;
79+
} else {
80+
$this->errors[] = APIResponse\get(5006);
81+
break;
82+
}
83+
}
5384
}
85+
}
86+
87+
private function __validate_disabled() {
88+
# Check for our optional `disabled` payload value
89+
if ($this->initial_data["disabled"] === true) {
90+
$this->validated_data["disabled"] = "";
91+
} elseif($this->initial_data["disabled"] === false) {
92+
unset($this->validated_data["disabled"]);
93+
}
94+
}
95+
96+
private function __validate_descr() {
97+
# Check for our optional `descr` payload value
5498
if (isset($this->initial_data['descr'])) {
55-
$descr = $this->initial_data['descr'];
56-
$descr = trim($descr);
57-
$this->validated_data["descr"] = $descr; // Update our user's full name
99+
$this->validated_data["descr"] = $this->initial_data['descr'];
58100
}
101+
}
102+
103+
private function __validate_expires() {
104+
# Check for our optional `expires` payload value
59105
if (isset($this->initial_data['expires'])) {
60-
$expires = $this->initial_data['expires'];
61-
$expires = trim($expires);
62-
$this->validated_data["expires"] = $expires; // Update our user's expiration date
106+
# Attempt to format the expiration date if the value is not empty
107+
if (!empty($this->initial_data["expires"])) {
108+
# Try to format the date string, return an error if the format is invalid
109+
try {
110+
$this->validated_data["expires"] = (new DateTime($this->initial_data['expires']))->format("m/d/Y");
111+
} catch (Exception $e) {
112+
$this->errors[] = APIResponse\get(5040);
113+
}
114+
}
115+
# Otherwise, if the value was blank, unset the expiration date
116+
else {
117+
unset($this->validated_data["expires"]);
118+
}
63119
}
120+
}
121+
122+
private function __validate_authorizedkeys() {
123+
# Check for our optional `authorizedkeys` payload value
64124
if (isset($this->initial_data['authorizedkeys'])) {
65-
$authorizedkeys = $this->initial_data['authorizedkeys'];
66-
$authorizedkeys = trim($authorizedkeys);
67-
$this->validated_data["authorizedkeys"] = $authorizedkeys; // Update our user's authorized keys
125+
$this->validated_data["authorizedkeys"] = base64_encode($this->initial_data['authorizedkeys']);
68126
}
127+
}
128+
129+
private function __validate_ipsecpsk() {
130+
# Check for our optional `ipsecpsk` payload value
69131
if (isset($this->initial_data['ipsecpsk'])) {
70-
$ipsecpsk = $this->initial_data['ipsecpsk'];
71-
$ipsecpsk = trim($ipsecpsk);
72-
$this->validated_data["ipsecpsk"] = $ipsecpsk; // Update our user's IPsec pre-shared key
132+
# Ensure the PSK does not contain invalid characters
133+
if (preg_match('/^[[:ascii:]]*$/', $_POST['ipsecpsk'])) {
134+
$this->validated_data["ipsecpsk"] = $this->initial_data['ipsecpsk'];
135+
} else {
136+
$this->errors[] = APIResponse\get(5039);
137+
}
73138
}
74-
$this->validated_data["scope"] = "user"; // Set our new user's system scope
139+
}
140+
141+
public function validate_payload() {
142+
# Run each validation method
143+
$this->__validate_username();
144+
$this->__validate_password();
145+
$this->__validate_priv();
146+
$this->__validate_descr();
147+
$this->__validate_disabled();
148+
$this->__validate_expires();
149+
$this->__validate_authorizedkeys();
150+
$this->__validate_ipsecpsk();
75151
}
76152
}

0 commit comments

Comments
 (0)