new API structure
This commit is contained in:
parent
a3ef5ac084
commit
9fc9a2a43f
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
|
||||
class Create extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->apiKeyAllowed = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$apiKey = generateRandomString(64);
|
||||
$sql = $this->user->getSQL();
|
||||
$validUntil = (new \DateTime())->modify("+30 DAY");
|
||||
|
||||
$this->success = $sql->insert("ApiKey", array("user_id", "api_key", "valid_until"))
|
||||
->addRow($this->user->getId(), $apiKey, $validUntil)
|
||||
->returning("uid")
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->result["api_key"] = array(
|
||||
"api_key" => $apiKey,
|
||||
"valid_until" => $validUntil->getTimestamp(),
|
||||
"uid" => $sql->getLastInsertId(),
|
||||
);
|
||||
} else {
|
||||
$this->result["api_key"] = null;
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
use DateTime;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
use Exception;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("uid", "api_key", "valid_until")
|
||||
->from("ApiKey")
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->where(new Compare("valid_until", $sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("active", true))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["api_keys"] = array();
|
||||
foreach($res as $row) {
|
||||
try {
|
||||
$validUntil = (new DateTime($row["valid_until"]))->getTimestamp();
|
||||
} catch (Exception $e) {
|
||||
$validUntil = $row["valid_until"];
|
||||
}
|
||||
|
||||
$this->result["api_keys"][] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"api_key" => $row["api_key"],
|
||||
"valid_until" => $validUntil,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
use \Api\Parameter\Parameter;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Refresh extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function apiKeyExists() {
|
||||
$id = $this->getParam("id");
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("ApiKey")
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->where(new Compare("valid_until", $sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("active", 1))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success && $res[0]["count"] === 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "This API-Key does not exist.";
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->getParam("id");
|
||||
if(!$this->apiKeyExists())
|
||||
return false;
|
||||
|
||||
$validUntil = (new \DateTime)->modify("+30 DAY");
|
||||
$sql = $this->user->getSQL();
|
||||
$this->success = $sql->update("ApiKey")
|
||||
->set("valid_until", $validUntil)
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->result["valid_until"] = $validUntil->getTimestamp();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
use \Api\Parameter\Parameter;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Revoke extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function apiKeyExists() {
|
||||
$id = $this->getParam("id");
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("ApiKey")
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->where(new Compare("valid_until", $sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("active", 1))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success && $res[0]["count"] === 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "This API-Key does not exist.";
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($aValues = array()) {
|
||||
if(!parent::execute($aValues)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->getParam("id");
|
||||
if(!$this->apiKeyExists())
|
||||
return false;
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$this->success = $sql->update("ApiKey")
|
||||
->set("active", false)
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
191
core/Api/ApiKeyAPI.class.php
Normal file
191
core/Api/ApiKeyAPI.class.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
class ApiKeyAPI extends Request {
|
||||
|
||||
protected function apiKeyExists($id) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("ApiKey")
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->where(new Compare("valid_until", $sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("active", 1))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success && $res[0]["count"] === 0) {
|
||||
return $this->createError("This API-Key does not exist.");
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Api\ApiKey {
|
||||
|
||||
use Api\ApiKeyAPI;
|
||||
use Api\Parameter\Parameter;
|
||||
use DateTime;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
use Exception;
|
||||
|
||||
class Create extends ApiKeyAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->apiKeyAllowed = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$apiKey = generateRandomString(64);
|
||||
$sql = $this->user->getSQL();
|
||||
$validUntil = (new \DateTime())->modify("+30 DAY");
|
||||
|
||||
$this->success = $sql->insert("ApiKey", array("user_id", "api_key", "valid_until"))
|
||||
->addRow($this->user->getId(), $apiKey, $validUntil)
|
||||
->returning("uid")
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->result["api_key"] = array(
|
||||
"api_key" => $apiKey,
|
||||
"valid_until" => $validUntil->getTimestamp(),
|
||||
"uid" => $sql->getLastInsertId(),
|
||||
);
|
||||
} else {
|
||||
$this->result["api_key"] = null;
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Fetch extends ApiKeyAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("uid", "api_key", "valid_until")
|
||||
->from("ApiKey")
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->where(new Compare("valid_until", $sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("active", true))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["api_keys"] = array();
|
||||
foreach($res as $row) {
|
||||
try {
|
||||
$validUntil = (new DateTime($row["valid_until"]))->getTimestamp();
|
||||
} catch (Exception $e) {
|
||||
$validUntil = $row["valid_until"];
|
||||
}
|
||||
|
||||
$this->result["api_keys"][] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"api_key" => $row["api_key"],
|
||||
"valid_until" => $validUntil,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Refresh extends ApiKeyAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->getParam("id");
|
||||
if(!$this->apiKeyExists($id))
|
||||
return false;
|
||||
|
||||
$validUntil = (new \DateTime)->modify("+30 DAY");
|
||||
$sql = $this->user->getSQL();
|
||||
$this->success = $sql->update("ApiKey")
|
||||
->set("valid_until", $validUntil)
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->result["valid_until"] = $validUntil->getTimestamp();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Revoke extends ApiKeyAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($aValues = array()) {
|
||||
if(!parent::execute($aValues)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = $this->getParam("id");
|
||||
if(!$this->apiKeyExists($id))
|
||||
return false;
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$this->success = $sql->update("ApiKey")
|
||||
->set("active", false)
|
||||
->where(new Compare("uid", $id))
|
||||
->where(new Compare("user_id", $this->user->getId()))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api;
|
||||
|
||||
class GetLanguages extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("uid", "code", "name")
|
||||
->from("Language")
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result['languages'] = array();
|
||||
if(empty($res) === 0) {
|
||||
$this->lastError = L("No languages found");
|
||||
} else {
|
||||
foreach($res as $row) {
|
||||
$this->result['languages'][$row['uid']] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Groups;
|
||||
|
||||
use \Api\Parameter\Parameter;
|
||||
use \Api\Request;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
const SELECT_SIZE = 10;
|
||||
|
||||
private int $groupCount;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->groupCount = 0;
|
||||
}
|
||||
|
||||
private function getGroupCount() {
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())->from("Group")->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->groupCount = $res[0]["count"];
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$page = $this->getParam("page");
|
||||
if($page < 1) {
|
||||
return $this->createError("Invalid page count");
|
||||
}
|
||||
|
||||
if (!$this->getGroupCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("Group.uid as groupId", "Group.name as groupName", $sql->count("UserGroup.user_id"))
|
||||
->from("Group")
|
||||
->innerJoin("UserGroup", "UserGroup.group_id", "Group.uid")
|
||||
->groupBy("Group.uid")
|
||||
->orderBy("Group.uid")
|
||||
->ascending()
|
||||
->limit(Fetch::SELECT_SIZE)
|
||||
->offset(($page - 1) * Fetch::SELECT_SIZE)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["groups"] = array();
|
||||
foreach($res as $row) {
|
||||
$groupId = intval($row["groupId"]);
|
||||
$groupName = $row["groupName"];
|
||||
$memberCount = $row["usergroup_user_id_count"];
|
||||
$this->result["groups"][$groupId] = array(
|
||||
"name" => $groupName,
|
||||
"memberCount" => $memberCount
|
||||
);
|
||||
}
|
||||
$this->result["pageCount"] = intval(ceil($this->groupCount / Fetch::SELECT_SIZE));
|
||||
$this->result["totalCount"] = $this->groupCount;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
94
core/Api/GroupsAPI.class.php
Normal file
94
core/Api/GroupsAPI.class.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
|
||||
class GroupsAPI extends Request {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Api\Groups {
|
||||
|
||||
use Api\GroupsAPI;
|
||||
use Api\Parameter\Parameter;
|
||||
|
||||
class Fetch extends GroupsAPI {
|
||||
|
||||
const SELECT_SIZE = 10;
|
||||
|
||||
private int $groupCount;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->groupCount = 0;
|
||||
}
|
||||
|
||||
private function getGroupCount() {
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())->from("Group")->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->groupCount = $res[0]["count"];
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$page = $this->getParam("page");
|
||||
if($page < 1) {
|
||||
return $this->createError("Invalid page count");
|
||||
}
|
||||
|
||||
if (!$this->getGroupCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("Group.uid as groupId", "Group.name as groupName", $sql->count("UserGroup.user_id"))
|
||||
->from("Group")
|
||||
->innerJoin("UserGroup", "UserGroup.group_id", "Group.uid")
|
||||
->groupBy("Group.uid")
|
||||
->orderBy("Group.uid")
|
||||
->ascending()
|
||||
->limit(Fetch::SELECT_SIZE)
|
||||
->offset(($page - 1) * Fetch::SELECT_SIZE)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["groups"] = array();
|
||||
foreach($res as $row) {
|
||||
$groupId = intval($row["groupId"]);
|
||||
$groupName = $row["groupName"];
|
||||
$memberCount = $row["usergroup_user_id_count"];
|
||||
$this->result["groups"][$groupId] = array(
|
||||
"name" => $groupName,
|
||||
"memberCount" => $memberCount
|
||||
);
|
||||
}
|
||||
$this->result["pageCount"] = intval(ceil($this->groupCount / Fetch::SELECT_SIZE));
|
||||
$this->result["totalCount"] = $this->groupCount;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
128
core/Api/LanguageAPI.class.php
Normal file
128
core/Api/LanguageAPI.class.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
|
||||
class LanguageAPI extends Request {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Api\Language {
|
||||
|
||||
use Api\LanguageAPI;
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
use Driver\SQL\Condition\CondOr;
|
||||
use Objects\Language;
|
||||
|
||||
class Get extends LanguageAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("uid", "code", "name")
|
||||
->from("Language")
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result['languages'] = array();
|
||||
if(empty($res) === 0) {
|
||||
$this->lastError = L("No languages found");
|
||||
} else {
|
||||
foreach($res as $row) {
|
||||
$this->result['languages'][$row['uid']] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Set extends LanguageAPI {
|
||||
|
||||
private Language $language;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'langId' => new Parameter('langId', Parameter::TYPE_INT, true, NULL),
|
||||
'langCode' => new StringType('langCode', 5, true, NULL),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function checkLanguage() {
|
||||
$langId = $this->getParam("langId");
|
||||
$langCode = $this->getParam("langCode");
|
||||
|
||||
if(is_null($langId) && is_null($langCode)) {
|
||||
return $this->createError(L("Either langId or langCode must be given"));
|
||||
}
|
||||
|
||||
$res = $this->user->getSQL()
|
||||
->select("uid", "code", "name")
|
||||
->from("Language")
|
||||
->where(new CondOr(new Compare("uid", $langId), new Compare("code", $langCode)))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $this->user->getSQL()->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if(count($res) == 0) {
|
||||
return $this->createError(L("This Language does not exist"));
|
||||
} else {
|
||||
$row = $res[0];
|
||||
$this->language = Language::newInstance($row['uid'], $row['code'], $row['name']);
|
||||
if(!$this->language) {
|
||||
return $this->createError(L("Error while loading language"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function updateLanguage() {
|
||||
$languageId = $this->language->getId();
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$this->success = $sql->update("User")
|
||||
->set("language_id", $languageId)
|
||||
->where(new Compare("uid", $userId))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkLanguage())
|
||||
return false;
|
||||
|
||||
if($this->user->isLoggedIn()) {
|
||||
$this->updateLanguage();
|
||||
}
|
||||
|
||||
$this->user->setLanguage($this->language);
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Notifications;
|
||||
|
||||
use \Api\Request;
|
||||
use \Api\Parameter\Parameter;
|
||||
use \Api\Parameter\StringType;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Create extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'groupId' => new Parameter('groupId', Parameter::TYPE_INT, true),
|
||||
'userId' => new Parameter('userId', Parameter::TYPE_INT, true),
|
||||
'title' => new StringType('title', 32),
|
||||
'message' => new StringType('message', 256),
|
||||
));
|
||||
$this->isPublic = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function checkUser($userId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("User")
|
||||
->where(new Compare("uid", $userId))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if ($res[0]["count"] == 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "User not found";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function insertUserNotification($userId, $notificationId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("UserNotification", array("user_id", "notification_id"))
|
||||
->addRow($userId, $notificationId)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function checkGroup($groupId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("Group")
|
||||
->where(new Compare("uid", $groupId))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if ($res[0]["count"] == 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "Group not found";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function insertGroupNotification($groupId, $notificationId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("GroupNotification", array("group_id", "notification_id"))
|
||||
->addRow($groupId, $notificationId)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function createNotification($title, $message) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("Notification", array("title", "message"))
|
||||
->addRow($title, $message)
|
||||
->returning("uid")
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
return $sql->getLastInsertId();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userId = $this->getParam("userId");
|
||||
$groupId = $this->getParam("groupId");
|
||||
$title = $this->getParam("title");
|
||||
$message = $this->getParam("message");
|
||||
|
||||
if (is_null($userId) && is_null($groupId)) {
|
||||
return $this->createError("Either userId or groupId must be specified.");
|
||||
} else if(!is_null($userId) && !is_null($groupId)) {
|
||||
return $this->createError("Only one of userId and groupId must be specified.");
|
||||
} else if(!is_null($userId)) {
|
||||
if ($this->checkUser($userId)) {
|
||||
$id = $this->createNotification($title, $message);
|
||||
if ($this->success) {
|
||||
return $this->insertUserNotification($userId, $id);
|
||||
}
|
||||
}
|
||||
} else if(!is_null($groupId)) {
|
||||
if ($this->checkGroup($groupId)) {
|
||||
$id = $this->createNotification($title, $message);
|
||||
if ($this->success) {
|
||||
return $this->insertGroupNotification($groupId, $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Notifications;
|
||||
|
||||
use \Api\Request;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
private array $notifications;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function fetchUserNotifications() {
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->distinct("Notification.uid"), "created_at", "title", "message")
|
||||
->from("Notification")
|
||||
->innerJoin("UserNotification", "UserNotification.notification_id", "Notification.uid")
|
||||
->where(new Compare("UserNotification.user_id", $userId))
|
||||
->where(new Compare("UserNotification.seen", false))
|
||||
->orderBy("created_at")->descending()
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
foreach($res as $row) {
|
||||
$id = $row["uid"];
|
||||
if (!isset($this->notifications[$id])) {
|
||||
$this->notifications[$id] = array(
|
||||
"uid" => $id,
|
||||
"title" => $row["title"],
|
||||
"message" => $row["message"],
|
||||
"created_at" => $row["created_at"],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function fetchGroupNotifications() {
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->distinct("Notification.uid"), "created_at", "title", "message")
|
||||
->from("Notification")
|
||||
->innerJoin("GroupNotification", "GroupNotification.notification_id", "Notification.uid")
|
||||
->innerJoin("UserGroup", "GroupNotification.group_id", "UserGroup.group_id")
|
||||
->where(new Compare("UserGroup.user_id", $userId))
|
||||
->where(new Compare("GroupNotification.seen", false))
|
||||
->orderBy("created_at")->descending()
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
foreach($res as $row) {
|
||||
$id = $row["uid"];
|
||||
if (!isset($this->notifications[$id])) {
|
||||
$this->notifications[] = array(
|
||||
"uid" => $id,
|
||||
"title" => $row["title"],
|
||||
"message" => $row["message"],
|
||||
"created_at" => $row["created_at"],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->notifications = array();
|
||||
if ($this->fetchUserNotifications() && $this->fetchGroupNotifications()) {
|
||||
$this->result["notifications"] = $this->notifications;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
231
core/Api/NotificationsAPI.class.php
Normal file
231
core/Api/NotificationsAPI.class.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
|
||||
class NotificationsAPI extends Request {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Api\Notifications {
|
||||
|
||||
use Api\NotificationsAPI;
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
class Create extends NotificationsAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'groupId' => new Parameter('groupId', Parameter::TYPE_INT, true),
|
||||
'userId' => new Parameter('userId', Parameter::TYPE_INT, true),
|
||||
'title' => new StringType('title', 32),
|
||||
'message' => new StringType('message', 256),
|
||||
));
|
||||
$this->isPublic = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function checkUser($userId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("User")
|
||||
->where(new Compare("uid", $userId))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if ($res[0]["count"] == 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "User not found";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function insertUserNotification($userId, $notificationId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("UserNotification", array("user_id", "notification_id"))
|
||||
->addRow($userId, $notificationId)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function checkGroup($groupId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())
|
||||
->from("Group")
|
||||
->where(new Compare("uid", $groupId))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if ($res[0]["count"] == 0) {
|
||||
$this->success = false;
|
||||
$this->lastError = "Group not found";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function insertGroupNotification($groupId, $notificationId) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("GroupNotification", array("group_id", "notification_id"))
|
||||
->addRow($groupId, $notificationId)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function createNotification($title, $message) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("Notification", array("title", "message"))
|
||||
->addRow($title, $message)
|
||||
->returning("uid")
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
return $sql->getLastInsertId();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userId = $this->getParam("userId");
|
||||
$groupId = $this->getParam("groupId");
|
||||
$title = $this->getParam("title");
|
||||
$message = $this->getParam("message");
|
||||
|
||||
if (is_null($userId) && is_null($groupId)) {
|
||||
return $this->createError("Either userId or groupId must be specified.");
|
||||
} else if(!is_null($userId) && !is_null($groupId)) {
|
||||
return $this->createError("Only one of userId and groupId must be specified.");
|
||||
} else if(!is_null($userId)) {
|
||||
if ($this->checkUser($userId)) {
|
||||
$id = $this->createNotification($title, $message);
|
||||
if ($this->success) {
|
||||
return $this->insertUserNotification($userId, $id);
|
||||
}
|
||||
}
|
||||
} else if(!is_null($groupId)) {
|
||||
if ($this->checkGroup($groupId)) {
|
||||
$id = $this->createNotification($title, $message);
|
||||
if ($this->success) {
|
||||
return $this->insertGroupNotification($groupId, $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Fetch extends NotificationsAPI {
|
||||
|
||||
private array $notifications;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function fetchUserNotifications() {
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->distinct("Notification.uid"), "created_at", "title", "message")
|
||||
->from("Notification")
|
||||
->innerJoin("UserNotification", "UserNotification.notification_id", "Notification.uid")
|
||||
->where(new Compare("UserNotification.user_id", $userId))
|
||||
->where(new Compare("UserNotification.seen", false))
|
||||
->orderBy("created_at")->descending()
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
foreach($res as $row) {
|
||||
$id = $row["uid"];
|
||||
if (!isset($this->notifications[$id])) {
|
||||
$this->notifications[$id] = array(
|
||||
"uid" => $id,
|
||||
"title" => $row["title"],
|
||||
"message" => $row["message"],
|
||||
"created_at" => $row["created_at"],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function fetchGroupNotifications() {
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->distinct("Notification.uid"), "created_at", "title", "message")
|
||||
->from("Notification")
|
||||
->innerJoin("GroupNotification", "GroupNotification.notification_id", "Notification.uid")
|
||||
->innerJoin("UserGroup", "GroupNotification.group_id", "UserGroup.group_id")
|
||||
->where(new Compare("UserGroup.user_id", $userId))
|
||||
->where(new Compare("GroupNotification.seen", false))
|
||||
->orderBy("created_at")->descending()
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
foreach($res as $row) {
|
||||
$id = $row["uid"];
|
||||
if (!isset($this->notifications[$id])) {
|
||||
$this->notifications[] = array(
|
||||
"uid" => $id,
|
||||
"title" => $row["title"],
|
||||
"message" => $row["message"],
|
||||
"created_at" => $row["created_at"],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->notifications = array();
|
||||
if ($this->fetchUserNotifications() && $this->fetchGroupNotifications()) {
|
||||
$this->result["notifications"] = $this->notifications;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Routes;
|
||||
|
||||
use \Api\Request;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$res = $sql
|
||||
->select("uid", "request", "action", "target", "extra", "active")
|
||||
->from("Route")
|
||||
->orderBy("uid")
|
||||
->ascending()
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
|
||||
if ($this->success) {
|
||||
$routes = array();
|
||||
foreach($res as $row) {
|
||||
$routes[] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"request" => $row["request"],
|
||||
"action" => $row["action"],
|
||||
"target" => $row["target"],
|
||||
"extra" => $row["extra"] ?? "",
|
||||
"active" => intval($row["active"]),
|
||||
);
|
||||
}
|
||||
|
||||
$this->result["routes"] = $routes;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Routes;
|
||||
|
||||
use Api\Parameter\StringType;
|
||||
use \Api\Request;
|
||||
use Driver\SQL\Column\Column;
|
||||
use Driver\SQL\Condition\CondBool;
|
||||
use Driver\SQL\Condition\Regex;
|
||||
|
||||
class Find extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'request' => new StringType('request', 128, true, '/')
|
||||
));
|
||||
|
||||
$this->isPublic = false;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$request = $this->getParam('request');
|
||||
if (!startsWith($request, '/')) {
|
||||
$request = "/$request";
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$res = $sql
|
||||
->select("uid", "request", "action", "target", "extra")
|
||||
->from("Route")
|
||||
->where(new CondBool("active"))
|
||||
->where(new Regex($request, new Column("request")))
|
||||
->limit(1)
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
|
||||
if ($this->success) {
|
||||
if (!empty($res)) {
|
||||
$row = $res[0];
|
||||
$this->result["route"] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"request" => $row["request"],
|
||||
"action" => $row["action"],
|
||||
"target" => $row["target"],
|
||||
"extra" => $row["extra"]
|
||||
);
|
||||
} else {
|
||||
$this->result["route"] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\Routes;
|
||||
|
||||
use Api\Parameter\Parameter;
|
||||
use \Api\Request;
|
||||
|
||||
class Save extends Request {
|
||||
|
||||
private array $routes;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'routes' => new Parameter('routes',Parameter::TYPE_ARRAY, false)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->validateRoutes()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
// DELETE old rules
|
||||
$this->success = ($sql->truncate("Route")->execute() !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
// INSERT new routes
|
||||
if ($this->success) {
|
||||
$stmt = $sql->insert("Route", array("request", "action", "target", "extra", "active"));
|
||||
foreach($this->routes as $route) {
|
||||
$stmt->addRow($route["request"], $route["action"], $route["target"], $route["extra"], $route["active"]);
|
||||
}
|
||||
$this->success = ($stmt->execute() !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function validateRoutes() {
|
||||
|
||||
$this->routes = array();
|
||||
$keys = array(
|
||||
"request" => Parameter::TYPE_STRING,
|
||||
"action" => Parameter::TYPE_STRING,
|
||||
"target" => Parameter::TYPE_STRING,
|
||||
"extra" => Parameter::TYPE_STRING,
|
||||
"active" => Parameter::TYPE_BOOLEAN
|
||||
);
|
||||
|
||||
$actions = array(
|
||||
"redirect_temporary", "redirect_permanently", "static", "dynamic"
|
||||
);
|
||||
|
||||
foreach($this->getParam("routes") as $index => $route) {
|
||||
foreach($keys as $key => $expectedType) {
|
||||
if (!array_key_exists($key, $route)) {
|
||||
return $this->createError("Route $index missing key: $key");
|
||||
}
|
||||
|
||||
$value = $route[$key];
|
||||
$type = Parameter::parseType($value);
|
||||
if ($type !== $expectedType && ($key !== "active" || !is_null($value))) {
|
||||
$expectedTypeName = Parameter::names[$expectedType];
|
||||
$gotTypeName = Parameter::names[$type];
|
||||
return $this->createError("Route $index has invalid value for key: $key, expected: $expectedTypeName, got: $gotTypeName");
|
||||
}
|
||||
}
|
||||
|
||||
$action = $route["action"];
|
||||
if (!in_array($action, $actions)) {
|
||||
return $this->createError("Invalid action: $action");
|
||||
}
|
||||
|
||||
if(empty($route["request"])) {
|
||||
return $this->createError("Request cannot be empty.");
|
||||
}
|
||||
|
||||
if(empty($route["target"])) {
|
||||
return $this->createError("Target cannot be empty.");
|
||||
}
|
||||
|
||||
$this->routes[] = $route;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
208
core/Api/RoutesAPI.class.php
Normal file
208
core/Api/RoutesAPI.class.php
Normal file
@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
abstract class RoutesAPI extends Request {
|
||||
}
|
||||
}
|
||||
|
||||
namespace Api\Routes {
|
||||
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Api\RoutesAPI;
|
||||
use Driver\SQL\Column\Column;
|
||||
use Driver\SQL\Condition\CondBool;
|
||||
use Driver\SQL\Condition\Regex;
|
||||
|
||||
class Fetch extends RoutesAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$res = $sql
|
||||
->select("uid", "request", "action", "target", "extra", "active")
|
||||
->from("Route")
|
||||
->orderBy("uid")
|
||||
->ascending()
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
|
||||
if ($this->success) {
|
||||
$routes = array();
|
||||
foreach($res as $row) {
|
||||
$routes[] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"request" => $row["request"],
|
||||
"action" => $row["action"],
|
||||
"target" => $row["target"],
|
||||
"extra" => $row["extra"] ?? "",
|
||||
"active" => intval($row["active"]),
|
||||
);
|
||||
}
|
||||
|
||||
$this->result["routes"] = $routes;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Find extends RoutesAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'request' => new StringType('request', 128, true, '/')
|
||||
));
|
||||
|
||||
$this->isPublic = false;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$request = $this->getParam('request');
|
||||
if (!startsWith($request, '/')) {
|
||||
$request = "/$request";
|
||||
}
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$res = $sql
|
||||
->select("uid", "request", "action", "target", "extra")
|
||||
->from("Route")
|
||||
->where(new CondBool("active"))
|
||||
->where(new Regex($request, new Column("request")))
|
||||
->limit(1)
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
|
||||
if ($this->success) {
|
||||
if (!empty($res)) {
|
||||
$row = $res[0];
|
||||
$this->result["route"] = array(
|
||||
"uid" => intval($row["uid"]),
|
||||
"request" => $row["request"],
|
||||
"action" => $row["action"],
|
||||
"target" => $row["target"],
|
||||
"extra" => $row["extra"]
|
||||
);
|
||||
} else {
|
||||
$this->result["route"] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Save extends RoutesAPI {
|
||||
|
||||
private array $routes;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'routes' => new Parameter('routes',Parameter::TYPE_ARRAY, false)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->validateRoutes()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
// DELETE old rules
|
||||
$this->success = ($sql->truncate("Route")->execute() !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
// INSERT new routes
|
||||
if ($this->success) {
|
||||
$stmt = $sql->insert("Route", array("request", "action", "target", "extra", "active"));
|
||||
foreach($this->routes as $route) {
|
||||
$stmt->addRow($route["request"], $route["action"], $route["target"], $route["extra"], $route["active"]);
|
||||
}
|
||||
$this->success = ($stmt->execute() !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function validateRoutes() {
|
||||
|
||||
$this->routes = array();
|
||||
$keys = array(
|
||||
"request" => Parameter::TYPE_STRING,
|
||||
"action" => Parameter::TYPE_STRING,
|
||||
"target" => Parameter::TYPE_STRING,
|
||||
"extra" => Parameter::TYPE_STRING,
|
||||
"active" => Parameter::TYPE_BOOLEAN
|
||||
);
|
||||
|
||||
$actions = array(
|
||||
"redirect_temporary", "redirect_permanently", "static", "dynamic"
|
||||
);
|
||||
|
||||
foreach($this->getParam("routes") as $index => $route) {
|
||||
foreach($keys as $key => $expectedType) {
|
||||
if (!array_key_exists($key, $route)) {
|
||||
return $this->createError("Route $index missing key: $key");
|
||||
}
|
||||
|
||||
$value = $route[$key];
|
||||
$type = Parameter::parseType($value);
|
||||
if ($type !== $expectedType && ($key !== "active" || !is_null($value))) {
|
||||
$expectedTypeName = Parameter::names[$expectedType];
|
||||
$gotTypeName = Parameter::names[$type];
|
||||
return $this->createError("Route $index has invalid value for key: $key, expected: $expectedTypeName, got: $gotTypeName");
|
||||
}
|
||||
}
|
||||
|
||||
$action = $route["action"];
|
||||
if (!in_array($action, $actions)) {
|
||||
return $this->createError("Invalid action: $action");
|
||||
}
|
||||
|
||||
if(empty($route["request"])) {
|
||||
return $this->createError("Request cannot be empty.");
|
||||
}
|
||||
|
||||
if(empty($route["target"])) {
|
||||
return $this->createError("Target cannot be empty.");
|
||||
}
|
||||
|
||||
$this->routes[] = $route;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api;
|
||||
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Driver\SQL\Condition\CondOr;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
use Objects\Language;
|
||||
|
||||
class SetLanguage extends Request {
|
||||
|
||||
private Language $language;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'langId' => new Parameter('langId', Parameter::TYPE_INT, true, NULL),
|
||||
'langCode' => new StringType('langCode', 5, true, NULL),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function checkLanguage() {
|
||||
$langId = $this->getParam("langId");
|
||||
$langCode = $this->getParam("langCode");
|
||||
|
||||
if(is_null($langId) && is_null($langCode)) {
|
||||
return $this->createError(L("Either langId or langCode must be given"));
|
||||
}
|
||||
|
||||
$res = $this->user->getSQL()
|
||||
->select("uid", "code", "name")
|
||||
->from("Language")
|
||||
->where(new CondOr(new Compare("uid", $langId), new Compare("code", $langCode)))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $this->user->getSQL()->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
if(count($res) == 0) {
|
||||
return $this->createError(L("This Language does not exist"));
|
||||
} else {
|
||||
$row = $res[0];
|
||||
$this->language = Language::newInstance($row['uid'], $row['code'], $row['name']);
|
||||
if(!$this->language) {
|
||||
return $this->createError(L("Error while loading language"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function updateLanguage() {
|
||||
$languageId = $this->language->getId();
|
||||
$userId = $this->user->getId();
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
$this->success = $sql->update("User")
|
||||
->set("language_id", $languageId)
|
||||
->where(new Compare("uid", $userId))
|
||||
->execute();
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkLanguage())
|
||||
return false;
|
||||
|
||||
if($this->user->isLoggedIn()) {
|
||||
$this->updateLanguage();
|
||||
}
|
||||
|
||||
$this->user->setLanguage($this->language);
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use Api\Parameter\StringType;
|
||||
use \Api\Request;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
class Create extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'email' => new StringType('email', 64, true),
|
||||
'password' => new StringType('password'),
|
||||
'confirmPassword' => new StringType('confirmPassword'),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->getParam('username');
|
||||
$email = $this->getParam('email');
|
||||
if (!$this->userExists($username, $email) || !$this->success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$password = $this->getParam('password');
|
||||
$confirmPassword = $this->getParam('confirmPassword');
|
||||
if ($password !== $confirmPassword) {
|
||||
return $this->createError("The given passwords do not match.");
|
||||
}
|
||||
|
||||
$this->success = $this->createUser($username, $email, $password);
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function userExists($username, $email) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("User.name", "User.email")
|
||||
->from("User")
|
||||
->where(new Compare("User.name", $username), new Compare("User.email", $email))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success && !empty($res)) {
|
||||
$row = $res[0];
|
||||
if (strcasecmp($username, $row['name']) === 0) {
|
||||
return $this->createError("This username is already taken.");
|
||||
} else if (strcasecmp($username, $row['email']) === 0) {
|
||||
return $this->createError("This email address is already in use.");
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function createUser($username, $email, $password) {
|
||||
$sql = $this->user->getSQL();
|
||||
$salt = generateRandomString(16);
|
||||
$hash = hash('sha256', $password . $salt);
|
||||
$res = $sql->insert("User", array("name", "password", "salt", "email"))
|
||||
->addRow($username, $hash, $salt, $email)
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use Api\Parameter\Parameter;
|
||||
use \Api\Request;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
const SELECT_SIZE = 10;
|
||||
|
||||
private int $userCount;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
$this->userCount = 0;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function getUserCount() {
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())->from("User")->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->userCount = $res[0]["count"];
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$page = $this->getParam("page");
|
||||
if($page < 1) {
|
||||
return $this->createError("Invalid page count");
|
||||
}
|
||||
|
||||
if (!$this->getUserCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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")
|
||||
->from("User")
|
||||
->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
|
||||
->leftJoin("Group", "Group.uid", "UserGroup.group_id")
|
||||
->orderBy("User.uid")
|
||||
->ascending()
|
||||
->limit(Fetch::SELECT_SIZE)
|
||||
->offset(($page - 1) * Fetch::SELECT_SIZE)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["users"] = array();
|
||||
foreach($res as $row) {
|
||||
$userId = intval($row["userId"]);
|
||||
$groupId = intval($row["groupId"]);
|
||||
$groupName = $row["groupName"];
|
||||
if (!isset($this->result["users"][$userId])) {
|
||||
$this->result["users"][$userId] = array(
|
||||
"uid" => $userId,
|
||||
"name" => $row["name"],
|
||||
"email" => $row["email"],
|
||||
"registered_at" => $row["registered_at"],
|
||||
"groups" => array(),
|
||||
);
|
||||
}
|
||||
|
||||
if(!is_null($groupId)) {
|
||||
$this->result["users"][$userId]["groups"][$groupId] = $groupName;
|
||||
}
|
||||
}
|
||||
$this->result["pageCount"] = intval(ceil($this->userCount / Fetch::SELECT_SIZE));
|
||||
$this->result["totalCount"] = $this->userCount;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use \Api\Request;
|
||||
|
||||
class Info extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->user->isLoggedIn()) {
|
||||
$this->result["loggedIn"] = false;
|
||||
} else {
|
||||
$this->result["loggedIn"] = true;
|
||||
}
|
||||
|
||||
$this->result["user"] = $this->user->jsonSerialize();
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use Api\Parameter\StringType;
|
||||
use \Api\Request;
|
||||
use Api\SendMail;
|
||||
use DateTime;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
class Invite extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'email' => new StringType('email', 64),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->getParam('username');
|
||||
$email = $this->getParam('email');
|
||||
if (!$this->userExists($username, $email) || !$this->success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//add to DB
|
||||
$token = generateRandomString(36);
|
||||
$valid_until = (new DateTime())->modify("+48 hour");
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("UserInvitation", array("username", "email", "token", "valid_until"))
|
||||
->addRow($username, $email, $token, $valid_until)
|
||||
->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
//send validation mail
|
||||
if($this->success) {
|
||||
$request = new SendMail($this->user);
|
||||
$link = "http://localhost/acceptInvitation?token=$token";
|
||||
$this->success = $request->execute(array(
|
||||
"from" => "webmaster@romanh.de",
|
||||
"to" => $email,
|
||||
"subject" => "Account Invitation for web-base@localhost",
|
||||
"body" =>
|
||||
"Hello,<br>
|
||||
you were invited to create an account on web-base@localhost. Click on the following link to confirm the registration, it is 48h valid from now.
|
||||
If the invitation was not intended, you can simply ignore this email.<br><br><a href=\"$link\">$link</a>"
|
||||
)
|
||||
);
|
||||
$this->lastError = $request->getLastError();
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function userExists($username, $email) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("User.name", "User.email")
|
||||
->from("User")
|
||||
->where(new Compare("User.name", $username), new Compare("User.email", $email))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success && !empty($res)) {
|
||||
$row = $res[0];
|
||||
if (strcasecmp($username, $row['name']) === 0) {
|
||||
return $this->createError("This username is already taken.");
|
||||
} else if (strcasecmp($username, $row['email']) === 0) {
|
||||
return $this->createError("This email address is already in use.");
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use \Api\Request;
|
||||
use \Api\Parameter\Parameter;
|
||||
use \Api\Parameter\StringType;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Login extends Request {
|
||||
|
||||
private int $startedAt;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'password' => new StringType('password'),
|
||||
'stayLoggedIn' => new Parameter('stayLoggedIn', Parameter::TYPE_BOOLEAN, true, true)
|
||||
));
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
private function wrongCredentials() {
|
||||
$runtime = microtime(true) - $this->startedAt;
|
||||
$sleepTime = round(3e6 - $runtime);
|
||||
if($sleepTime > 0) usleep($sleepTime);
|
||||
return $this->createError(L('Wrong username or password'));
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->user->isLoggedIn()) {
|
||||
$this->lastError = L('You are already logged in');
|
||||
$this->success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->startedAt = microtime(true);
|
||||
$this->success = false;
|
||||
$username = $this->getParam('username');
|
||||
$password = $this->getParam('password');
|
||||
$stayLoggedIn = $this->getParam('stayLoggedIn');
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("User.uid", "User.password", "User.salt")
|
||||
->from("User")
|
||||
->where(new Compare("User.name", $username))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
if(count($res) === 0) {
|
||||
return $this->wrongCredentials();
|
||||
} else {
|
||||
$row = $res[0];
|
||||
$salt = $row['salt'];
|
||||
$uid = $row['uid'];
|
||||
$hash = hash('sha256', $password . $salt);
|
||||
if($hash === $row['password']) {
|
||||
if(!($this->success = $this->user->createSession($uid, $stayLoggedIn))) {
|
||||
return $this->createError("Error creating Session: " . $sql->getLastError());
|
||||
} else {
|
||||
$this->result["loggedIn"] = true;
|
||||
$this->result['logoutIn'] = $this->user->getSession()->getExpiresSeconds();
|
||||
$this->success = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $this->wrongCredentials();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use \Api\Request;
|
||||
|
||||
class Logout extends Request {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall);
|
||||
$this->loginRequired = true;
|
||||
$this->apiKeyAllowed = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->success = $this->user->logout();
|
||||
$this->lastError = $this->user->getSQL()->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
|
||||
use Api\Parameter\StringType;
|
||||
use Api\SendMail;
|
||||
use Api\User\Create;
|
||||
|
||||
class Register extends Create{
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall);
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if ($this->user->isLoggedIn()) {
|
||||
$this->lastError = L('You are already logged in');
|
||||
$this->success = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->success) {
|
||||
$email = $this->getParam('email');
|
||||
$token = generateRandomString(36);
|
||||
$request = new SendMail($this->user);
|
||||
$link = "http://localhost/acceptInvitation?token=$token";
|
||||
$this->success = $request->execute(array(
|
||||
"from" => "webmaster@romanh.de",
|
||||
"to" => $email,
|
||||
"subject" => "Account Invitation for web-base@localhost",
|
||||
"body" =>
|
||||
"Hello,<br>
|
||||
you were invited to create an account on web-base@localhost. Click on the following link to confirm the registration, it is 48h valid from now.
|
||||
If the invitation was not intended, you can simply ignore this email.<br><br><a href=\"$link\">$link</a>"
|
||||
)
|
||||
);
|
||||
$this->lastError = $request->getLastError();
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
}
|
442
core/Api/UserAPI.class.php
Normal file
442
core/Api/UserAPI.class.php
Normal file
@ -0,0 +1,442 @@
|
||||
<?php
|
||||
|
||||
namespace Api {
|
||||
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
abstract class UserAPI extends Request {
|
||||
|
||||
protected function userExists($username, $email) {
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("User.name", "User.email")
|
||||
->from("User")
|
||||
->where(new Compare("User.name", $username), new Compare("User.email", $email))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success && !empty($res)) {
|
||||
$row = $res[0];
|
||||
if (strcasecmp($username, $row['name']) === 0) {
|
||||
return $this->createError("This username is already taken.");
|
||||
} else if (strcasecmp($username, $row['email']) === 0) {
|
||||
return $this->createError("This email address is already in use.");
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
protected function insertUser($username, $email, $password) {
|
||||
$sql = $this->user->getSQL();
|
||||
$salt = generateRandomString(16);
|
||||
$hash = $this->hashPassword($password, $salt);
|
||||
$res = $sql->insert("User", array("name", "password", "salt", "email"))
|
||||
->addRow($username, $hash, $salt, $email)
|
||||
->returning("uid")
|
||||
->execute();
|
||||
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = ($res !== FALSE);
|
||||
|
||||
if ($this->success) {
|
||||
return $sql->getLastInsertId();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
// TODO: replace this with crypt() in the future
|
||||
protected function hashPassword($password, $salt) {
|
||||
return hash('sha256', $password . $salt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Api\User {
|
||||
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Api\SendMail;
|
||||
use Api\UserAPI;
|
||||
use DateTime;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
|
||||
class Create extends UserAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'email' => new StringType('email', 64, true),
|
||||
'password' => new StringType('password'),
|
||||
'confirmPassword' => new StringType('confirmPassword'),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->getParam('username');
|
||||
$email = $this->getParam('email');
|
||||
if (!$this->userExists($username, $email) || !$this->success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$password = $this->getParam('password');
|
||||
$confirmPassword = $this->getParam('confirmPassword');
|
||||
if ($password !== $confirmPassword) {
|
||||
return $this->createError("The given passwords do not match.");
|
||||
}
|
||||
|
||||
return $this->insertUser($username, $email, $password) !== FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
class Fetch extends UserAPI {
|
||||
|
||||
const SELECT_SIZE = 10;
|
||||
|
||||
private int $userCount;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1)
|
||||
));
|
||||
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
$this->userCount = 0;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
private function getUserCount() {
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select($sql->count())->from("User")->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$this->userCount = $res[0]["count"];
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$page = $this->getParam("page");
|
||||
if($page < 1) {
|
||||
return $this->createError("Invalid page count");
|
||||
}
|
||||
|
||||
if (!$this->getUserCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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")
|
||||
->from("User")
|
||||
->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
|
||||
->leftJoin("Group", "Group.uid", "UserGroup.group_id")
|
||||
->orderBy("User.uid")
|
||||
->ascending()
|
||||
->limit(Fetch::SELECT_SIZE)
|
||||
->offset(($page - 1) * Fetch::SELECT_SIZE)
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
$this->result["users"] = array();
|
||||
foreach($res as $row) {
|
||||
$userId = intval($row["userId"]);
|
||||
$groupId = intval($row["groupId"]);
|
||||
$groupName = $row["groupName"];
|
||||
if (!isset($this->result["users"][$userId])) {
|
||||
$this->result["users"][$userId] = array(
|
||||
"uid" => $userId,
|
||||
"name" => $row["name"],
|
||||
"email" => $row["email"],
|
||||
"registered_at" => $row["registered_at"],
|
||||
"groups" => array(),
|
||||
);
|
||||
}
|
||||
|
||||
if(!is_null($groupId)) {
|
||||
$this->result["users"][$userId]["groups"][$groupId] = $groupName;
|
||||
}
|
||||
}
|
||||
$this->result["pageCount"] = intval(ceil($this->userCount / Fetch::SELECT_SIZE));
|
||||
$this->result["totalCount"] = $this->userCount;
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Info extends UserAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->user->isLoggedIn()) {
|
||||
$this->result["loggedIn"] = false;
|
||||
} else {
|
||||
$this->result["loggedIn"] = true;
|
||||
}
|
||||
|
||||
$this->result["user"] = $this->user->jsonSerialize();
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Invite extends UserAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'email' => new StringType('email', 64),
|
||||
));
|
||||
$this->csrfTokenRequired = true;
|
||||
$this->loginRequired = true;
|
||||
$this->requiredGroup = USER_GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->getParam('username');
|
||||
$email = $this->getParam('email');
|
||||
if (!$this->userExists($username, $email)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//add to DB
|
||||
$token = generateRandomString(36);
|
||||
$valid_until = (new DateTime())->modify("+48 hour");
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("UserInvitation", array("username", "email", "token", "valid_until"))
|
||||
->addRow($username, $email, $token, $valid_until)
|
||||
->execute();
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
//send validation mail
|
||||
if($this->success) {
|
||||
$request = new SendMail($this->user);
|
||||
$link = "http://localhost/acceptInvitation?token=$token";
|
||||
$this->success = $request->execute(array(
|
||||
"from" => "webmaster@romanh.de",
|
||||
"to" => $email,
|
||||
"subject" => "Account Invitation for web-base@localhost",
|
||||
"body" =>
|
||||
"Hello,<br>
|
||||
you were invited to create an account on web-base@localhost. Click on the following link to confirm the registration, it is 48h valid from now.
|
||||
If the invitation was not intended, you can simply ignore this email.<br><br><a href=\"$link\">$link</a>"
|
||||
)
|
||||
);
|
||||
$this->lastError = $request->getLastError();
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Login extends UserAPI {
|
||||
|
||||
private int $startedAt;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'password' => new StringType('password'),
|
||||
'stayLoggedIn' => new Parameter('stayLoggedIn', Parameter::TYPE_BOOLEAN, true, true)
|
||||
));
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
private function wrongCredentials() {
|
||||
$runtime = microtime(true) - $this->startedAt;
|
||||
$sleepTime = round(3e6 - $runtime);
|
||||
if($sleepTime > 0) usleep($sleepTime);
|
||||
return $this->createError(L('Wrong username or password'));
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->user->isLoggedIn()) {
|
||||
$this->lastError = L('You are already logged in');
|
||||
$this->success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->startedAt = microtime(true);
|
||||
$this->success = false;
|
||||
$username = $this->getParam('username');
|
||||
$password = $this->getParam('password');
|
||||
$stayLoggedIn = $this->getParam('stayLoggedIn');
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->select("User.uid", "User.password", "User.salt")
|
||||
->from("User")
|
||||
->where(new Compare("User.name", $username))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
|
||||
if($this->success) {
|
||||
if(count($res) === 0) {
|
||||
return $this->wrongCredentials();
|
||||
} else {
|
||||
$row = $res[0];
|
||||
$salt = $row['salt'];
|
||||
$uid = $row['uid'];
|
||||
$hash = $this->hashPassword($password, $salt);
|
||||
if($hash === $row['password']) {
|
||||
if(!($this->success = $this->user->createSession($uid, $stayLoggedIn))) {
|
||||
return $this->createError("Error creating Session: " . $sql->getLastError());
|
||||
} else {
|
||||
$this->result["loggedIn"] = true;
|
||||
$this->result['logoutIn'] = $this->user->getSession()->getExpiresSeconds();
|
||||
$this->success = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $this->wrongCredentials();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Logout extends UserAPI {
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall);
|
||||
$this->loginRequired = true;
|
||||
$this->apiKeyAllowed = false;
|
||||
$this->csrfTokenRequired = true;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if(!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->success = $this->user->logout();
|
||||
$this->lastError = $this->user->getSQL()->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Register extends UserAPI {
|
||||
|
||||
private ?int $userId;
|
||||
private string $token;
|
||||
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"username" => new StringType("username", 32),
|
||||
"email" => new StringType("email", 64),
|
||||
"password" => new StringType("password"),
|
||||
"confirmPassword" => new StringType("confirmPassword"),
|
||||
));
|
||||
}
|
||||
|
||||
private function insertToken() {
|
||||
$validUntil = (new DateTime())->modify("+48 hour");
|
||||
$sql = $this->user->getSQL();
|
||||
$res = $sql->insert("UserToken", array("user_id", "token", "token_type", "valid_until"))
|
||||
->addRow(array($this->userId, $this->token, "confirmation", $validUntil))
|
||||
->execute();
|
||||
|
||||
$this->success = ($res !== FALSE);
|
||||
$this->lastError = $sql->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
if (!parent::execute($values)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->user->isLoggedIn()) {
|
||||
$this->lastError = L('You are already logged in');
|
||||
$this->success = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->getParam("username");
|
||||
$email = $this->getParam('email');
|
||||
if (!$this->userExists($username, $email)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$password = $this->getParam("password");
|
||||
$confirmPassword = $this->getParam("confirmPassword");
|
||||
if(strcmp($password, $confirmPassword) !== 0) {
|
||||
return $this->createError("The given passwords don't match");
|
||||
}
|
||||
|
||||
$id = $this->insertUser($username, $email, $password);
|
||||
if ($id === FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->userId = $id;
|
||||
$this->token = generateRandomString(36);
|
||||
if ($this->insertToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$request = new SendMail($this->user);
|
||||
$link = "http://localhost/confirmEmail?token=$this->token";
|
||||
$this->success = $request->execute(array(
|
||||
"from" => "webmaster@romanh.de",
|
||||
"to" => $email,
|
||||
"subject" => "E-Mail Confirmation for web-base@localhost",
|
||||
"body" =>
|
||||
"Hello,<br>
|
||||
you recently registered an account on web-base@localhost. Click on the following link to confirm the registration, it is 48h valid from now.
|
||||
If the registration was not intended, you can simply ignore this email.<br><br><a href=\"$link\">$link</a>"
|
||||
)
|
||||
);
|
||||
|
||||
if (!$this->success) {
|
||||
$this->lastError = "Your account was registered but the confirmation email could not be sent. " .
|
||||
"Please contact the server administration. Reason: " . $request->getLastError();
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Objects;
|
||||
|
||||
use Api\SetLanguage;
|
||||
use Configuration\Configuration;
|
||||
use DateTime;
|
||||
use Driver\SQL\Expression\Add;
|
||||
@ -108,7 +107,7 @@ class User extends ApiObject {
|
||||
|
||||
public function updateLanguage($lang) {
|
||||
if($this->sql) {
|
||||
$request = new SetLanguage($this);
|
||||
$request = new \Api\Language\Set($this);
|
||||
return $request->execute(array("langCode" => $lang));
|
||||
} else {
|
||||
return false;
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Views;
|
||||
|
||||
use Api\GetLanguages;
|
||||
use Elements\View;
|
||||
|
||||
class LanguageFlags extends View {
|
||||
@ -17,7 +16,7 @@ class LanguageFlags extends View {
|
||||
public function loadView() {
|
||||
parent::loadView();
|
||||
|
||||
$request = new GetLanguages($this->getDocument()->getUser());
|
||||
$request = new \Api\Language\Get($this->getDocument()->getUser());
|
||||
if($request->execute()) {
|
||||
|
||||
$requestUri = $_SERVER["REQUEST_URI"];
|
||||
|
@ -87,7 +87,14 @@
|
||||
|
||||
function getClassPath($class, $suffix=true) {
|
||||
$path = str_replace('\\', '/', $class);
|
||||
if (startsWith($path, "/")) $path = substr($path, 1);
|
||||
$path = array_values(array_filter(explode("/", $path)));
|
||||
|
||||
if (strcasecmp($path[0], "api") === 0 && count($path) > 2 && strcasecmp($path[1], "Parameter") !== 0) {
|
||||
$path = "Api/" . $path[1] . "API";
|
||||
} else {
|
||||
$path = implode("/", $path);
|
||||
}
|
||||
|
||||
$suffix = ($suffix ? ".class" : "");
|
||||
return "core/$path$suffix.php";
|
||||
}
|
||||
|
42
index.php
42
index.php
@ -41,21 +41,35 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
|
||||
header("400 Bad Request");
|
||||
$response = createError("Invalid Method");
|
||||
} else {
|
||||
$apiFunction = implode("\\", array_map('ucfirst', explode("/", $apiFunction)));
|
||||
if($apiFunction[0] !== "\\") $apiFunction = "\\$apiFunction";
|
||||
$class = "\\Api$apiFunction";
|
||||
$file = getClassPath($class);
|
||||
if(!file_exists($file)) {
|
||||
header("404 Not Found");
|
||||
$response = createError("Not found");
|
||||
} else if(!is_subclass_of($class, Request::class)) {
|
||||
header("400 Bad Request");
|
||||
$response = createError("Invalid Method");
|
||||
$apiFunction = array_filter(array_map('ucfirst', explode("/", $apiFunction)));
|
||||
if (count($apiFunction) > 1) {
|
||||
$parentClass = "\\Api\\" . reset($apiFunction) . "API";
|
||||
$apiClass = "\\Api\\" . implode("\\", $apiFunction);
|
||||
} else {
|
||||
$request = new $class($user, true);
|
||||
$success = $request->execute();
|
||||
$msg = $request->getLastError();
|
||||
$response = $request->getJsonResult();
|
||||
$apiClass = "\\Api\\" . implode("\\", $apiFunction);
|
||||
$parentClass = $apiClass;
|
||||
}
|
||||
|
||||
try {
|
||||
$file = getClassPath($parentClass);
|
||||
if(!file_exists($file)) {
|
||||
header("404 Not Found");
|
||||
$response = createError("Not found");
|
||||
} else {
|
||||
$parentClass = new ReflectionClass($parentClass);
|
||||
$apiClass = new ReflectionClass($apiClass);
|
||||
if(!$apiClass->isSubclassOf(Request::class) || !$apiClass->isInstantiable()) {
|
||||
header("400 Bad Request");
|
||||
$response = createError("Invalid Method");
|
||||
} else {
|
||||
$request = $apiClass->newInstanceArgs(array($user, true));
|
||||
$success = $request->execute();
|
||||
$msg = $request->getLastError();
|
||||
$response = $request->getJsonResult();
|
||||
}
|
||||
}
|
||||
} catch (ReflectionException $e) {
|
||||
$response = createError("Error instantiating class: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user