EditUser API

This commit is contained in:
Roman Hergenreder 2020-06-23 17:55:52 +02:00
parent 77ec99e845
commit 71570c700f
2 changed files with 128 additions and 25 deletions

@ -6,11 +6,25 @@ namespace Api {
abstract class UserAPI extends Request { abstract class UserAPI extends Request {
protected function userExists($username, $email) { protected function userExists(?string $username, ?string $email) {
$conditions = array();
if (!is_null($username) && !empty($username)) {
$conditions[] = new Compare("User.name", $username);
}
if (!is_null($email) && !empty($email)) {
$conditions[] = new Compare("User.email", $email);
}
if (empty($conditions)) {
return true;
}
$sql = $this->user->getSQL(); $sql = $this->user->getSQL();
$res = $sql->select("User.name", "User.email") $res = $sql->select("User.name", "User.email")
->from("User") ->from("User")
->where(new Compare("User.name", $username), new Compare("User.email", $email)) ->where(...$conditions)
->execute(); ->execute();
$this->success = ($res !== FALSE); $this->success = ($res !== FALSE);
@ -70,6 +84,22 @@ namespace Api {
return array(); return array();
} }
protected function getUser($id) {
$sql = $this->user->getSQL();
$res = $sql->select("User.uid as userId", "User.name", "User.email", "User.registered_at",
"Group.uid as groupId", "Group.name as groupName", "Group.color as groupColor")
->from("User")
->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
->leftJoin("Group", "Group.uid", "UserGroup.group_id")
->where(new Compare("User.uid", $id))
->execute();
$this->success = ($res !== FALSE);
$this->lastError = $sql->getLastError();
return ($this->success && !empty($res) ? $res : array());
}
} }
} }
@ -82,6 +112,7 @@ namespace Api\User {
use Api\UserAPI; use Api\UserAPI;
use DateTime; use DateTime;
use Driver\SQL\Condition\Compare; use Driver\SQL\Condition\Compare;
use Objects\User;
class Create extends UserAPI { class Create extends UserAPI {
@ -104,7 +135,7 @@ namespace Api\User {
$username = $this->getParam('username'); $username = $this->getParam('username');
$email = $this->getParam('email'); $email = $this->getParam('email');
if (!$this->userExists($username, $email) || !$this->success) { if (!$this->userExists($username, $email)) {
return false; return false;
} }
@ -232,33 +263,21 @@ namespace Api\User {
} }
$id = $this->getParam("id"); $id = $this->getParam("id");
$user = $this->getUser($id);
$sql = $this->user->getSQL();
$res = $sql->select("User.uid as userId", "User.name", "User.email", "User.registered_at",
"Group.uid as groupId", "Group.name as groupName", "Group.color as groupColor")
->from("User")
->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
->leftJoin("Group", "Group.uid", "UserGroup.group_id")
->where(new Compare("User.uid", $id))
->execute();
$this->success = ($res !== FALSE);
$this->lastError = $sql->getLastError();
if ($this->success) { if ($this->success) {
if (empty($res)) { if (empty($user)) {
return $this->createError("User not found"); return $this->createError("User not found");
} else { } else {
$row = $res[0];
$this->result["user"] = array( $this->result["user"] = array(
"uid" => $row["userId"], "uid" => $user[0]["userId"],
"name" => $row["name"], "name" => $user[0]["name"],
"email" => $row["email"], "email" => $user[0]["email"],
"registered_at" => $row["registered_at"], "registered_at" => $user[0]["registered_at"],
"groups" => array() "groups" => array()
); );
foreach($res as $row) { foreach($user as $row) {
$this->result["user"]["groups"][] = array( $this->result["user"]["groups"][] = array(
"uid" => $row["groupId"], "uid" => $row["groupId"],
"name" => $row["groupName"], "name" => $row["groupName"],
@ -548,5 +567,81 @@ If the registration was not intended, you can simply ignore this email.<br><br><
} }
} }
class Edit extends UserAPI {
public function __construct(User $user, bool $externalCall) {
parent::__construct($user, $externalCall, array(
'id' => new Parameter('id', Parameter::TYPE_INT),
'username' => new StringType('username', 32, true, NULL),
'email' => new StringType('email', 64, true, NULL),
'password' => new StringType('password', -1, true, NULL),
'groups' => new Parameter('groups', Parameter::TYPE_ARRAY, true, NULL),
));
$this->requiredGroup = array(USER_GROUP_ADMIN);
$this->loginRequired = true;
}
public function execute($values = array()) {
if (!parent::execute($values)) {
return false;
}
$id = $this->getParam("id");
$user = $this->getUser($id);
if ($this->success) {
if (empty($user)) {
return $this->createError("User not found");
}
$username = $this->getParam("username");
$email = $this->getParam("email");
$password = $this->getParam("password");
$groups = $this->getParam("groups");
if (!is_null($groups)) {
if ($id === $this->user->getId() && !in_array(USER_GROUP_ADMIN, $groups)) {
return $this->createError("Cannot remove Administrator group from own user.");
}
}
// Check for duplicate username, email
$usernameChanged = !is_null($username) ? strcasecmp($username, $this->user->getUsername()) !== 0 : false;
$emailChanged = !is_null($email) ? strcasecmp($email, $this->user->getEmail()) !== 0 : false;
if($usernameChanged || $emailChanged) {
if (!$this->userExists($usernameChanged ? $username : NULL, $emailChanged ? $email : NULL)) {
return false;
}
}
$sql = $this->user->getSQL();
$query = $sql->update("User");
if ($usernameChanged) $query->set("name", $username);
if ($emailChanged) $query->set("email", $email);
if (!is_null($password)) $query->set("password", $this->hashPassword($password, $user[0]["salt"]));
$query->where(new Compare("User.uid", $id));
$res = $query->execute();
$this->lastError = $sql->getLastError();
$this->success = ($res !== FALSE);
if ($this->success && !is_null($groups)) {
$deleteQuery = $sql->delete("UserGroup")->where(new Compare("user_id", $id));
$insertQuery = $sql->insert("UserGroup", array("user_id", "group_id"));
foreach($groups as $groupId) {
$insertQuery->addRow(array($id, $groupId));
}
$this->success = ($deleteQuery->execute() !== FALSE) && ($insertQuery->execute() !== FALSE);
$this->lastError = $sql->getLastError();
}
}
return $this->success;
}
}
} }

@ -20,6 +20,7 @@ class User extends ApiObject {
private ?Session $session; private ?Session $session;
private int $uid; private int $uid;
private string $username; private string $username;
private string $email;
private Language $language; private Language $language;
private array $groups; private array $groups;
@ -50,6 +51,7 @@ class User extends ApiObject {
public function getId() { return $this->uid; } public function getId() { return $this->uid; }
public function isLoggedIn() { return $this->loggedIn; } public function isLoggedIn() { return $this->loggedIn; }
public function getUsername() { return $this->username; } public function getUsername() { return $this->username; }
public function getEmail() { return $this->email; }
public function getSQL() { return $this->sql; } public function getSQL() { return $this->sql; }
public function getLanguage() { return $this->language; } public function getLanguage() { return $this->language; }
public function setLanguage(Language $language) { $this->language = $language; $language->load(); } public function setLanguage(Language $language) { $this->language = $language; $language->load(); }
@ -77,6 +79,7 @@ class User extends ApiObject {
return array( return array(
'uid' => $this->uid, 'uid' => $this->uid,
'name' => $this->username, 'name' => $this->username,
'email' => $this->email,
'groups' => $this->groups, 'groups' => $this->groups,
'language' => $this->language->jsonSerialize(), 'language' => $this->language->jsonSerialize(),
'session' => $this->session->jsonSerialize(), 'session' => $this->session->jsonSerialize(),
@ -91,6 +94,7 @@ class User extends ApiObject {
private function reset() { private function reset() {
$this->uid = 0; $this->uid = 0;
$this->username = ''; $this->username = '';
$this->email = '';
$this->loggedIn = false; $this->loggedIn = false;
$this->session = null; $this->session = null;
} }
@ -125,7 +129,8 @@ class User extends ApiObject {
public function readData($userId, $sessionId, $sessionUpdate = true) { public function readData($userId, $sessionId, $sessionUpdate = true) {
$res = $this->sql->select("User.name", "Language.uid as langId", "Language.code as langCode", "Language.name as langName", $res = $this->sql->select("User.name", "User.email",
"Language.uid as langId", "Language.code as langCode", "Language.name as langName",
"Session.data", "Session.stay_logged_in", "Session.csrf_token", "Group.uid as groupId", "Group.name as groupName") "Session.data", "Session.stay_logged_in", "Session.csrf_token", "Group.uid as groupId", "Group.name as groupName")
->from("User") ->from("User")
->innerJoin("Session", "Session.user_id", "User.uid") ->innerJoin("Session", "Session.user_id", "User.uid")
@ -146,6 +151,7 @@ class User extends ApiObject {
$row = $res[0]; $row = $res[0];
$csrfToken = $row["csrf_token"]; $csrfToken = $row["csrf_token"];
$this->username = $row['name']; $this->username = $row['name'];
$this->email = $row["email"];
$this->uid = $userId; $this->uid = $userId;
$this->session = new Session($this, $sessionId, $csrfToken); $this->session = new Session($this, $sessionId, $csrfToken);
$this->session->setData(json_decode($row["data"] ?? '{}')); $this->session->setData(json_decode($row["data"] ?? '{}'));
@ -209,7 +215,8 @@ class User extends ApiObject {
if($this->loggedIn) if($this->loggedIn)
return true; return true;
$res = $this->sql->select("ApiKey.user_id as uid", "User.name as username", "Language.uid as langId", "Language.code as langCode", "Language.name as langName") $res = $this->sql->select("ApiKey.user_id as uid", "User.name", "User.email",
"Language.uid as langId", "Language.code as langCode", "Language.name as langName")
->from("ApiKey") ->from("ApiKey")
->innerJoin("User", "ApiKey.user_id", "User.uid") ->innerJoin("User", "ApiKey.user_id", "User.uid")
->leftJoin("Language", "User.language_id", "Language.uid") ->leftJoin("Language", "User.language_id", "Language.uid")
@ -225,7 +232,8 @@ class User extends ApiObject {
} else { } else {
$row = $res[0]; $row = $res[0];
$this->uid = $row['uid']; $this->uid = $row['uid'];
$this->username = $row['username']; $this->username = $row['name'];
$this->email = $row['email'];
if(!is_null($row['langId'])) { if(!is_null($row['langId'])) {
$this->setLanguage(Language::newInstance($row['langId'], $row['langCode'], $row['langName'])); $this->setLanguage(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));