Permission stuff
This commit is contained in:
parent
be6d48ac10
commit
e48ea51a5a
@ -37,8 +37,6 @@ namespace Api\Groups {
|
|||||||
'count' => new Parameter('count', Parameter::TYPE_INT, true, 20)
|
'count' => new Parameter('count', Parameter::TYPE_INT, true, 20)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN);
|
|
||||||
$this->groupCount = 0;
|
$this->groupCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +114,6 @@ namespace Api\Groups {
|
|||||||
'name' => new StringType('name', 32),
|
'name' => new StringType('name', 32),
|
||||||
'color' => new StringType('color', 10),
|
'color' => new StringType('color', 10),
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -165,9 +160,6 @@ namespace Api\Groups {
|
|||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'uid' => new Parameter('uid', Parameter::TYPE_INT)
|
'uid' => new Parameter('uid', Parameter::TYPE_INT)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
|
120
core/Api/MailAPI.class.php
Normal file
120
core/Api/MailAPI.class.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
class MailAPI extends Request {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Api\Mail {
|
||||||
|
|
||||||
|
use Api\MailAPI;
|
||||||
|
use Api\Parameter\Parameter;
|
||||||
|
use Api\Parameter\StringType;
|
||||||
|
use External\PHPMailer\Exception;
|
||||||
|
use External\PHPMailer\PHPMailer;
|
||||||
|
use Objects\ConnectionData;
|
||||||
|
use Objects\User;
|
||||||
|
|
||||||
|
class Test extends MailAPI {
|
||||||
|
|
||||||
|
public function __construct(User $user, bool $externalCall = false) {
|
||||||
|
parent::__construct($user, $externalCall, array(
|
||||||
|
"receiver" => new Parameter("receiver", Parameter::TYPE_EMAIL)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute($values = array()) {
|
||||||
|
if (!parent::execute($values)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$receiver = $this->getParam("receiver");
|
||||||
|
$req = new \Api\Mail\Send($this->user);
|
||||||
|
$this->success = $req->execute(array(
|
||||||
|
"to" => $receiver,
|
||||||
|
"subject" => "Test E-Mail",
|
||||||
|
"body" => "Hey! If you receive this e-mail, your mail configuration seems to be working."
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->lastError = $req->getLastError();
|
||||||
|
return $this->success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Send extends MailAPI {
|
||||||
|
public function __construct($user, $externalCall = false) {
|
||||||
|
parent::__construct($user, $externalCall, array(
|
||||||
|
'to' => new Parameter('to', Parameter::TYPE_EMAIL),
|
||||||
|
'subject' => new StringType('subject', -1),
|
||||||
|
'body' => new StringType('body', -1),
|
||||||
|
));
|
||||||
|
$this->isPublic = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getMailConfig() : ?ConnectionData {
|
||||||
|
$req = new \Api\Settings\Get($this->user);
|
||||||
|
$this->success = $req->execute(array("key" => "^mail_"));
|
||||||
|
$this->lastError = $req->getLastError();
|
||||||
|
|
||||||
|
if ($this->success) {
|
||||||
|
$settings = $req->getResult()["settings"];
|
||||||
|
|
||||||
|
if (!isset($settings["mail_enabled"]) || $settings["mail_enabled"] !== "1") {
|
||||||
|
$this->createError("Mail is not configured yet.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = $settings["mail_host"] ?? "localhost";
|
||||||
|
$port = intval($settings["mail_port"] ?? "25");
|
||||||
|
$login = $settings["mail_username"] ?? "";
|
||||||
|
$password = $settings["mail_password"] ?? "";
|
||||||
|
$connectionData = new ConnectionData($host, $port, $login, $password);
|
||||||
|
$connectionData->setProperty("from", $settings["mail_from"] ?? "");
|
||||||
|
return $connectionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute($values = array()) {
|
||||||
|
if(!parent::execute($values)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mailConfig = $this->getMailConfig();
|
||||||
|
if (!$this->success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$mail = new PHPMailer;
|
||||||
|
$mail->IsSMTP();
|
||||||
|
$mail->setFrom($mailConfig->getProperty("from"));
|
||||||
|
$mail->addAddress($this->getParam('to'));
|
||||||
|
$mail->Subject = $this->getParam('subject');
|
||||||
|
$mail->SMTPDebug = 0;
|
||||||
|
$mail->Host = $mailConfig->getHost();
|
||||||
|
$mail->Port = $mailConfig->getPort();
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $mailConfig->getLogin();
|
||||||
|
$mail->Password = $mailConfig->getPassword();
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->IsHTML(true);
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
$mail->Body = $this->getParam('body');
|
||||||
|
|
||||||
|
$this->success = @$mail->Send();
|
||||||
|
if (!$this->success) {
|
||||||
|
$this->lastError = "Error sending Mail: $mail->ErrorInfo";
|
||||||
|
error_log("sendMail() failed: $mail->ErrorInfo");
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->success = false;
|
||||||
|
$this->lastError = "Error sending Mail: $e";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,6 @@ namespace Api\Notifications {
|
|||||||
'message' => new StringType('message', 256),
|
'message' => new StringType('message', 256),
|
||||||
));
|
));
|
||||||
$this->isPublic = false;
|
$this->isPublic = false;
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkUser($userId) {
|
private function checkUser($userId) {
|
||||||
|
@ -18,7 +18,11 @@ namespace Api\Permission {
|
|||||||
use Api\Parameter\Parameter;
|
use Api\Parameter\Parameter;
|
||||||
use Api\Parameter\StringType;
|
use Api\Parameter\StringType;
|
||||||
use Api\PermissionAPI;
|
use Api\PermissionAPI;
|
||||||
|
use Driver\SQL\Column\Column;
|
||||||
use Driver\SQL\Condition\Compare;
|
use Driver\SQL\Condition\Compare;
|
||||||
|
use Driver\SQL\Condition\CondIn;
|
||||||
|
use Driver\SQL\Condition\CondNot;
|
||||||
|
use Driver\SQL\Strategy\UpdateStrategy;
|
||||||
use Objects\User;
|
use Objects\User;
|
||||||
|
|
||||||
class Check extends PermissionAPI {
|
class Check extends PermissionAPI {
|
||||||
@ -57,6 +61,7 @@ namespace Api\Permission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->user->isLoggedIn() || empty(array_intersect($groups, array_keys($this->user->getGroups())))) {
|
if (!$this->user->isLoggedIn() || empty(array_intersect($groups, array_keys($this->user->getGroups())))) {
|
||||||
|
header('HTTP 1.1 401 Unauthorized');
|
||||||
return $this->createError("Permission denied.");
|
return $this->createError("Permission denied.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +80,7 @@ namespace Api\Permission {
|
|||||||
|
|
||||||
private function fetchGroups() {
|
private function fetchGroups() {
|
||||||
$sql = $this->user->getSQL();
|
$sql = $this->user->getSQL();
|
||||||
$res = $sql->select("uid", "name")
|
$res = $sql->select("uid", "name", "color")
|
||||||
->from("Group")
|
->from("Group")
|
||||||
->orderBy("uid")
|
->orderBy("uid")
|
||||||
->ascending()
|
->ascending()
|
||||||
@ -89,7 +94,8 @@ namespace Api\Permission {
|
|||||||
foreach($res as $row) {
|
foreach($res as $row) {
|
||||||
$groupId = $row["uid"];
|
$groupId = $row["uid"];
|
||||||
$groupName = $row["name"];
|
$groupName = $row["name"];
|
||||||
$this->groups[$groupId] = $groupName;
|
$groupColor = $row["color"];
|
||||||
|
$this->groups[$groupId] = array("name" => $groupName, "color" => $groupColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +116,7 @@ namespace Api\Permission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql = $this->user->getSQL();
|
$sql = $this->user->getSQL();
|
||||||
$res = $sql->select("method", "groups")
|
$res = $sql->select("method", "groups", "description")
|
||||||
->from("ApiPermission")
|
->from("ApiPermission")
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
@ -121,8 +127,13 @@ namespace Api\Permission {
|
|||||||
$permissions = array();
|
$permissions = array();
|
||||||
foreach ($res as $row) {
|
foreach ($res as $row) {
|
||||||
$method = $row["method"];
|
$method = $row["method"];
|
||||||
|
$description = $row["description"];
|
||||||
$groups = json_decode($row["groups"]);
|
$groups = json_decode($row["groups"]);
|
||||||
$permissions[] = array("method" => $method, "groups" => $groups);
|
$permissions[] = array(
|
||||||
|
"method" => $method,
|
||||||
|
"groups" => $groups,
|
||||||
|
"description" => $description
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$this->result["permissions"] = $permissions;
|
$this->result["permissions"] = $permissions;
|
||||||
$this->result["groups"] = $this->groups;
|
$this->result["groups"] = $this->groups;
|
||||||
@ -149,7 +160,52 @@ namespace Api\Permission {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$permissions = $this->getParam("permissions");
|
||||||
|
$sql = $this->user->getSQL();
|
||||||
|
$methodParam = new StringType('method', 32);
|
||||||
|
$groupsParam = new Parameter('groups', Parameter::TYPE_ARRAY);
|
||||||
|
|
||||||
|
$updateQuery = $sql->insert("ApiPermission", array("method", "groups"))
|
||||||
|
->onDuplicateKeyStrategy(new UpdateStrategy(array("method"), array( "groups" => new Column("groups") )));
|
||||||
|
|
||||||
|
$insertedMethods = array();
|
||||||
|
|
||||||
|
foreach($permissions as $permission) {
|
||||||
|
if (!is_array($permission)) {
|
||||||
|
return $this->createError("Invalid data type found in parameter: permissions, expected: object");
|
||||||
|
} else if(!isset($permission["method"]) || !array_key_exists("groups", $permission)) {
|
||||||
|
return $this->createError("Invalid object found in parameter: permissions, expected keys 'method' and 'groups'");
|
||||||
|
} else if (!$methodParam->parseParam($permission["method"])) {
|
||||||
|
$expectedType = $methodParam->getTypeName();
|
||||||
|
return $this->createError("Invalid data type found for attribute 'method', expected: $expectedType");
|
||||||
|
} else if(!$groupsParam->parseParam($permission["groups"])) {
|
||||||
|
$expectedType = $groupsParam->getTypeName();
|
||||||
|
return $this->createError("Invalid data type found for attribute 'groups', expected: $expectedType");
|
||||||
|
} else if(empty(trim($methodParam->value))) {
|
||||||
|
return $this->createError("Method cannot be empty.");
|
||||||
|
} else {
|
||||||
|
$method = $methodParam->value;
|
||||||
|
$groups = $groupsParam->value;
|
||||||
|
$updateQuery->addRow($method, $groups);
|
||||||
|
$insertedMethods[] = $method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($permissions)) {
|
||||||
|
$res = $updateQuery->execute();
|
||||||
|
$this->success = ($res !== FALSE);
|
||||||
|
$this->lastError = $sql->getLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->success) {
|
||||||
|
$res = $sql->delete("ApiPermission")
|
||||||
|
->where(new Compare("description", "")) // only delete non default permissions
|
||||||
|
->where(new CondNot(new CondIn("method", $insertedMethods)))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$this->success = ($res !== FALSE);
|
||||||
|
$this->lastError = $sql->getLastError();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ class Request {
|
|||||||
protected bool $variableParamCount;
|
protected bool $variableParamCount;
|
||||||
protected bool $isDisabled;
|
protected bool $isDisabled;
|
||||||
protected bool $apiKeyAllowed;
|
protected bool $apiKeyAllowed;
|
||||||
protected array $requiredGroup;
|
|
||||||
protected bool $csrfTokenRequired;
|
protected bool $csrfTokenRequired;
|
||||||
|
|
||||||
private array $aDefaultParams;
|
private array $aDefaultParams;
|
||||||
@ -36,7 +35,6 @@ class Request {
|
|||||||
$this->variableParamCount = false;
|
$this->variableParamCount = false;
|
||||||
$this->apiKeyAllowed = true;
|
$this->apiKeyAllowed = true;
|
||||||
$this->allowedMethods = array("GET", "POST");
|
$this->allowedMethods = array("GET", "POST");
|
||||||
$this->requiredGroup = array();
|
|
||||||
$this->lastError = "";
|
$this->lastError = "";
|
||||||
$this->csrfTokenRequired = true;
|
$this->csrfTokenRequired = true;
|
||||||
}
|
}
|
||||||
@ -54,15 +52,13 @@ class Request {
|
|||||||
|
|
||||||
$isEmpty = (is_string($value) || is_array($value)) && empty($value);
|
$isEmpty = (is_string($value) || is_array($value)) && empty($value);
|
||||||
if(!$param->optional && (is_null($value) || $isEmpty)) {
|
if(!$param->optional && (is_null($value) || $isEmpty)) {
|
||||||
$this->lastError = 'Missing parameter: ' . $name;
|
return $this->createError("Missing parameter: $name");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_null($value) && !$isEmpty) {
|
if(!is_null($value) && !$isEmpty) {
|
||||||
if(!$param->parseParam($value)) {
|
if(!$param->parseParam($value)) {
|
||||||
$value = print_r($value, true);
|
$value = print_r($value, true);
|
||||||
$this->lastError = "Invalid Type for parameter: $name '$value' (Required: " . $param->getTypeName() . ")";
|
return $this->createError("Invalid Type for parameter: $name '$value' (Required: " . $param->getTypeName() . ")");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,26 +131,25 @@ class Request {
|
|||||||
header('HTTP 1.1 401 Unauthorized');
|
header('HTTP 1.1 401 Unauthorized');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CSRF Token
|
// CSRF Token
|
||||||
if($this->csrfTokenRequired && !$apiKeyAuthorized) {
|
if($this->csrfTokenRequired && $this->user->isLoggedIn()) {
|
||||||
// csrf token required + external call
|
// csrf token required + external call
|
||||||
// if it's not a call with API_KEY, check for csrf_token
|
// if it's not a call with API_KEY, check for csrf_token
|
||||||
if (!isset($values["csrf_token"]) || strcmp($values["csrf_token"], $this->user->getSession()->getCsrfToken()) !== 0) {
|
if (!isset($values["csrf_token"]) || strcmp($values["csrf_token"], $this->user->getSession()->getCsrfToken()) !== 0) {
|
||||||
$this->lastError = "CSRF-Token mismatch";
|
$this->lastError = "CSRF-Token mismatch";
|
||||||
header('HTTP 1.1 403 Forbidden');
|
header('HTTP 1.1 403 Forbidden');
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for permission
|
// Check for permission
|
||||||
if (!($this instanceof PermissionAPI)) {
|
if (!($this instanceof \Api\Permission\Save)) {
|
||||||
$req = new \Api\Permission\Check($this->user);
|
$req = new \Api\Permission\Check($this->user);
|
||||||
$this->success = $req->execute(array("method" => $this->getMethod()));
|
$this->success = $req->execute(array("method" => $this->getMethod()));
|
||||||
$this->lastError = $req->getLastError();
|
$this->lastError = $req->getLastError();
|
||||||
if (!$this->success) {
|
if (!$this->success) {
|
||||||
header('HTTP 1.1 401 Unauthorized');
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,6 @@ namespace Api\Routes {
|
|||||||
|
|
||||||
public function __construct($user, $externalCall = false) {
|
public function __construct($user, $externalCall = false) {
|
||||||
parent::__construct($user, $externalCall, array());
|
parent::__construct($user, $externalCall, array());
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -133,9 +131,6 @@ namespace Api\Routes {
|
|||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'routes' => new Parameter('routes',Parameter::TYPE_ARRAY, false)
|
'routes' => new Parameter('routes',Parameter::TYPE_ARRAY, false)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Api;
|
|
||||||
use Api\Parameter\Parameter;
|
|
||||||
use Api\Parameter\StringType;
|
|
||||||
use External\PHPMailer\Exception;
|
|
||||||
use External\PHPMailer\PHPMailer;
|
|
||||||
use Objects\ConnectionData;
|
|
||||||
|
|
||||||
class SendMail extends Request {
|
|
||||||
|
|
||||||
public function __construct($user, $externalCall = false) {
|
|
||||||
parent::__construct($user, $externalCall, array(
|
|
||||||
'to' => new Parameter('to', Parameter::TYPE_EMAIL),
|
|
||||||
'subject' => new StringType('subject', -1),
|
|
||||||
'body' => new StringType('body', -1),
|
|
||||||
));
|
|
||||||
$this->isPublic = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getMailConfig() : ?ConnectionData {
|
|
||||||
$req = new \Api\Settings\Get($this->user);
|
|
||||||
$this->success = $req->execute(array("key" => "^mail_"));
|
|
||||||
$this->lastError = $req->getLastError();
|
|
||||||
|
|
||||||
if ($this->success) {
|
|
||||||
$settings = $req->getResult()["settings"];
|
|
||||||
|
|
||||||
if (!isset($settings["mail_enabled"]) || $settings["mail_enabled"] !== "1") {
|
|
||||||
$this->createError("Mail is not configured yet.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$host = $settings["mail_host"] ?? "localhost";
|
|
||||||
$port = intval($settings["mail_port"] ?? "25");
|
|
||||||
$login = $settings["mail_username"] ?? "";
|
|
||||||
$password = $settings["mail_password"] ?? "";
|
|
||||||
$connectionData = new ConnectionData($host, $port, $login, $password);
|
|
||||||
$connectionData->setProperty("from", $settings["mail_from"] ?? "");
|
|
||||||
return $connectionData;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute($values = array()) {
|
|
||||||
if(!parent::execute($values)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mailConfig = $this->getMailConfig();
|
|
||||||
if (!$this->success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$mail = new PHPMailer;
|
|
||||||
$mail->IsSMTP();
|
|
||||||
$mail->setFrom($mailConfig->getProperty("from"));
|
|
||||||
$mail->addAddress($this->getParam('to'));
|
|
||||||
$mail->Subject = $this->getParam('subject');
|
|
||||||
$mail->SMTPDebug = 0;
|
|
||||||
$mail->Host = $mailConfig->getHost();
|
|
||||||
$mail->Port = $mailConfig->getPort();
|
|
||||||
$mail->SMTPAuth = true;
|
|
||||||
$mail->Username = $mailConfig->getLogin();
|
|
||||||
$mail->Password = $mailConfig->getPassword();
|
|
||||||
$mail->SMTPSecure = 'tls';
|
|
||||||
$mail->IsHTML(true);
|
|
||||||
$mail->CharSet = 'UTF-8';
|
|
||||||
$mail->Body = $this->getParam('body');
|
|
||||||
|
|
||||||
$this->success = @$mail->Send();
|
|
||||||
if (!$this->success) {
|
|
||||||
$this->lastError = "Error sending Mail: $mail->ErrorInfo";
|
|
||||||
error_log("sendMail() failed: $mail->ErrorInfo");
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->success = false;
|
|
||||||
$this->lastError = "Error sending Mail: $e";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->success;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Api;
|
|
||||||
|
|
||||||
use Api\Parameter\Parameter;
|
|
||||||
use Objects\User;
|
|
||||||
|
|
||||||
class SendTestMail extends Request {
|
|
||||||
|
|
||||||
public function __construct(User $user, bool $externalCall = false) {
|
|
||||||
parent::__construct($user, $externalCall, array(
|
|
||||||
"receiver" => new Parameter("receiver", Parameter::TYPE_EMAIL)
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute($values = array()) {
|
|
||||||
if (!parent::execute($values)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$receiver = $this->getParam("receiver");
|
|
||||||
$req = new SendMail($this->user);
|
|
||||||
$this->success = $req->execute(array(
|
|
||||||
"to" => $receiver,
|
|
||||||
"subject" => "Test E-Mail",
|
|
||||||
"body" => "Hey! If you receive this e-mail, your mail configuration seems to be working."
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->lastError = $req->getLastError();
|
|
||||||
return $this->success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -25,11 +25,8 @@ namespace Api\Settings {
|
|||||||
|
|
||||||
public function __construct(User $user, bool $externalCall = false) {
|
public function __construct(User $user, bool $externalCall = false) {
|
||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'key' => new StringType('key', 32, true, NULL)
|
'key' => new StringType('key', -1, true, NULL)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
$this->loginRequired = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -73,9 +70,6 @@ namespace Api\Settings {
|
|||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'settings' => new Parameter('settings', Parameter::TYPE_ARRAY)
|
'settings' => new Parameter('settings', Parameter::TYPE_ARRAY)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
$this->loginRequired = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
|
@ -7,11 +7,11 @@ use Driver\SQL\Condition\CondBool;
|
|||||||
|
|
||||||
class Stats extends Request {
|
class Stats extends Request {
|
||||||
|
|
||||||
|
private bool $mailConfigured;
|
||||||
|
private bool $recaptchaConfigured;
|
||||||
|
|
||||||
public function __construct($user, $externalCall = false) {
|
public function __construct($user, $externalCall = false) {
|
||||||
parent::__construct($user, $externalCall, array());
|
parent::__construct($user, $externalCall, array());
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getUserCount() {
|
private function getUserCount() {
|
||||||
@ -67,12 +67,15 @@ class Stats extends Request {
|
|||||||
return $visitors;
|
return $visitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isMailConfigured() {
|
private function checkSettings() {
|
||||||
$req = new \Api\Settings\Get($this->user);
|
$req = new \Api\Settings\Get($this->user);
|
||||||
$this->success = $req->execute(array("key" => "^mail_enabled$"));
|
$this->success = $req->execute(array("key" => "^(mail_enabled|recaptcha_enabled)$"));
|
||||||
|
$this->lastError = $req->getLastError();
|
||||||
|
|
||||||
if ($this->success) {
|
if ($this->success) {
|
||||||
return ($req->getResult()["mail_enabled"] ?? "0") === "1";
|
$settings = $req->getResult()["settings"];
|
||||||
|
$this->mailConfigured = ($settings["mail_enabled"] ?? "0") === "1";
|
||||||
|
$this->recaptchaConfigured = ($settings["recaptcha_enabled"] ?? "0") === "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
@ -95,8 +98,7 @@ class Stats extends Request {
|
|||||||
$loadAvg = sys_getloadavg();
|
$loadAvg = sys_getloadavg();
|
||||||
}
|
}
|
||||||
|
|
||||||
$mailConfigured = $this->isMailConfigured();
|
if (!$this->checkSettings()) {
|
||||||
if (!$this->success) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +111,8 @@ class Stats extends Request {
|
|||||||
"memory_usage" => memory_get_usage(),
|
"memory_usage" => memory_get_usage(),
|
||||||
"load_avg" => $loadAvg,
|
"load_avg" => $loadAvg,
|
||||||
"database" => $this->user->getSQL()->getStatus(),
|
"database" => $this->user->getSQL()->getStatus(),
|
||||||
"mail" => $mailConfigured
|
"mail" => $this->mailConfigured,
|
||||||
|
"reCaptcha" => $this->recaptchaConfigured
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->success;
|
return $this->success;
|
||||||
|
@ -118,7 +118,6 @@ namespace Api\User {
|
|||||||
|
|
||||||
use Api\Parameter\Parameter;
|
use Api\Parameter\Parameter;
|
||||||
use Api\Parameter\StringType;
|
use Api\Parameter\StringType;
|
||||||
use Api\SendMail;
|
|
||||||
use Api\UserAPI;
|
use Api\UserAPI;
|
||||||
use Api\VerifyCaptcha;
|
use Api\VerifyCaptcha;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
@ -137,7 +136,6 @@ namespace Api\User {
|
|||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
$this->loginRequired = true;
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -179,15 +177,10 @@ namespace Api\User {
|
|||||||
private int $userCount;
|
private int $userCount;
|
||||||
|
|
||||||
public function __construct($user, $externalCall = false) {
|
public function __construct($user, $externalCall = false) {
|
||||||
|
|
||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1),
|
'page' => new Parameter('page', Parameter::TYPE_INT, true, 1),
|
||||||
'count' => new Parameter('count', Parameter::TYPE_INT, true, 20)
|
'count' => new Parameter('count', Parameter::TYPE_INT, true, 20)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN);
|
|
||||||
$this->userCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getUserCount() {
|
private function getUserCount() {
|
||||||
@ -297,13 +290,9 @@ namespace Api\User {
|
|||||||
class Get extends UserAPI {
|
class Get extends UserAPI {
|
||||||
|
|
||||||
public function __construct($user, $externalCall = false) {
|
public function __construct($user, $externalCall = false) {
|
||||||
|
|
||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
'id' => new Parameter('id', Parameter::TYPE_INT)
|
'id' => new Parameter('id', Parameter::TYPE_INT)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
|
||||||
$this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -373,7 +362,6 @@ namespace Api\User {
|
|||||||
));
|
));
|
||||||
|
|
||||||
$this->loginRequired = true;
|
$this->loginRequired = true;
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
@ -418,7 +406,7 @@ namespace Api\User {
|
|||||||
$body = str_replace("{{{$key}}}", $value, $body);
|
$body = str_replace("{{{$key}}}", $value, $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = new SendMail($this->user);
|
$request = new \Api\Mail\Send($this->user);
|
||||||
$this->success = $request->execute(array(
|
$this->success = $request->execute(array(
|
||||||
"to" => $email,
|
"to" => $email,
|
||||||
"subject" => "[$siteName] Account Invitation",
|
"subject" => "[$siteName] Account Invitation",
|
||||||
@ -560,18 +548,6 @@ namespace Api\User {
|
|||||||
return $this->success;
|
return $this->success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkSettings() {
|
|
||||||
$req = new \Api\Settings\Get($this->user);
|
|
||||||
$this->success = $req->execute(array("key" => "user_registration_enabled"));
|
|
||||||
$this->lastError = $req->getLastError();
|
|
||||||
|
|
||||||
if ($this->success) {
|
|
||||||
return ($req->getResult()["user_registration_enabled"] ?? "0") === "1";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function execute($values = array()) {
|
public function execute($values = array()) {
|
||||||
if (!parent::execute($values)) {
|
if (!parent::execute($values)) {
|
||||||
return false;
|
return false;
|
||||||
@ -581,11 +557,7 @@ namespace Api\User {
|
|||||||
return $this->createError(L('You are already logged in'));
|
return $this->createError(L('You are already logged in'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$registrationAllowed = $this->checkSettings();
|
$registrationAllowed = $this->user->getConfiguration()->getSettings()->isRegistrationAllowed();
|
||||||
if (!$this->success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$registrationAllowed) {
|
if(!$registrationAllowed) {
|
||||||
return $this->createError("User Registration is not enabled.");
|
return $this->createError("User Registration is not enabled.");
|
||||||
}
|
}
|
||||||
@ -640,7 +612,7 @@ namespace Api\User {
|
|||||||
$body = str_replace("{{{$key}}}", $value, $body);
|
$body = str_replace("{{{$key}}}", $value, $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = new SendMail($this->user);
|
$request = new \Api\Mail\Send($this->user);
|
||||||
$this->success = $request->execute(array(
|
$this->success = $request->execute(array(
|
||||||
"to" => $email,
|
"to" => $email,
|
||||||
"subject" => "[$siteName] E-Mail Confirmation",
|
"subject" => "[$siteName] E-Mail Confirmation",
|
||||||
@ -696,7 +668,6 @@ namespace Api\User {
|
|||||||
'groups' => new Parameter('groups', Parameter::TYPE_ARRAY, true, NULL),
|
'groups' => new Parameter('groups', Parameter::TYPE_ARRAY, true, NULL),
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
$this->loginRequired = true;
|
$this->loginRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,7 +757,6 @@ namespace Api\User {
|
|||||||
'id' => new Parameter('id', Parameter::TYPE_INT)
|
'id' => new Parameter('id', Parameter::TYPE_INT)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->requiredGroup = array(USER_GROUP_ADMIN);
|
|
||||||
$this->loginRequired = true;
|
$this->loginRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,39 +174,30 @@ class CreateDatabase {
|
|||||||
$queries[] = $sql->createTable("ApiPermission")
|
$queries[] = $sql->createTable("ApiPermission")
|
||||||
->addString("method", 32)
|
->addString("method", 32)
|
||||||
->addJson("groups", true, '[]')
|
->addJson("groups", true, '[]')
|
||||||
|
->addString("description", 128, false, "")
|
||||||
->primaryKey("method");
|
->primaryKey("method");
|
||||||
|
|
||||||
$queries[] = $sql->insert("ApiPermission", array("method", "groups"))
|
$queries[] = $sql->insert("ApiPermission", array("method", "groups", "description"))
|
||||||
->addRow("ApiKey/create", array())
|
->addRow("ApiKey/create", array(), "Allows users to create API-Keys for themselves")
|
||||||
->addRow("ApiKey/fetch", array())
|
->addRow("ApiKey/fetch", array(), "Allows users to list their API-Keys")
|
||||||
->addRow("ApiKey/refresh", array())
|
->addRow("ApiKey/refresh", array(), "Allows users to refresh their API-Keys")
|
||||||
->addRow("ApiKey/revoke", array())
|
->addRow("ApiKey/revoke", array(), "Allows users to revoke their API-Keys")
|
||||||
->addRow("Contact/request", array())
|
->addRow("Groups/fetch", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to list all available groups")
|
||||||
->addRow("Groups/fetch", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN))
|
->addRow("Groups/create", array(USER_GROUP_ADMIN), "Allows users to create a new groups")
|
||||||
->addRow("Groups/create", array(USER_GROUP_ADMIN))
|
->addRow("Groups/delete", array(USER_GROUP_ADMIN), "Allows users to delete a group")
|
||||||
->addRow("Groups/delete", array(USER_GROUP_ADMIN))
|
->addRow("Routes/fetch", array(USER_GROUP_ADMIN), "Allows users to list all configured routes")
|
||||||
->addRow("Language/get", array())
|
->addRow("Routes/save", array(USER_GROUP_ADMIN), "Allows users to create, delete and modify routes")
|
||||||
->addRow("Language/set", array())
|
->addRow("Mail/test", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to send a test email to a given address")
|
||||||
->addRow("Notifications/create", array(USER_GROUP_ADMIN))
|
->addRow("Settings/get", array(USER_GROUP_ADMIN), "Allows users to fetch server settings")
|
||||||
->addRow("Notifications/fetch", array())
|
->addRow("Settings/set", array(USER_GROUP_ADMIN), "Allows users create, delete or modify server settings")
|
||||||
->addRow("Notifications/seen", array())
|
->addRow("Stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to fetch server stats")
|
||||||
->addRow("Routes/fetch", array(USER_GROUP_ADMIN))
|
->addRow("User/create", array(USER_GROUP_ADMIN), "Allows users to create a new user, email address does not need to be confirmed")
|
||||||
->addRow("Routes/save", array(USER_GROUP_ADMIN))
|
->addRow("User/fetch", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to list all registered users")
|
||||||
->addRow("sendTestMail", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN))
|
->addRow("User/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to get information about a single user")
|
||||||
->addRow("Settings/get", array(USER_GROUP_ADMIN))
|
->addRow("User/invite", array(USER_GROUP_ADMIN), "Allows users to create a new user and send them an invitation link")
|
||||||
->addRow("Settings/set", array(USER_GROUP_ADMIN))
|
->addRow("User/edit", array(USER_GROUP_ADMIN), "Allows users to edit details and group memberships of any user")
|
||||||
->addRow("Stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT))
|
->addRow("User/delete", array(USER_GROUP_ADMIN), "Allows users to delete any other user")
|
||||||
->addRow("User/create", array(USER_GROUP_ADMIN))
|
->addRow("Permission/fetch", array(USER_GROUP_ADMIN), "Allows users to list all API permissions");
|
||||||
->addRow("User/fetch", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT))
|
|
||||||
->addRow("User/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT))
|
|
||||||
->addRow("User/info", array())
|
|
||||||
->addRow("User/invite", array(USER_GROUP_ADMIN))
|
|
||||||
->addRow("User/login", array())
|
|
||||||
->addRow("User/logout", array())
|
|
||||||
->addRow("User/register", array())
|
|
||||||
->addRow("User/checkToken", array())
|
|
||||||
->addRow("User/edit", array(USER_GROUP_ADMIN))
|
|
||||||
->addRow("User/delete", array(USER_GROUP_ADMIN));
|
|
||||||
|
|
||||||
return $queries;
|
return $queries;
|
||||||
}
|
}
|
||||||
|
@ -81,23 +81,27 @@ class Settings {
|
|||||||
->addRow("recaptcha_private_key", $this->recaptchaPrivateKey, true, false);
|
->addRow("recaptcha_private_key", $this->recaptchaPrivateKey, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSiteName() {
|
public function getSiteName() : string {
|
||||||
return $this->siteName;
|
return $this->siteName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBaseUrl() {
|
public function getBaseUrl() : string {
|
||||||
return $this->baseUrl;
|
return $this->baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isRecaptchaEnabled() {
|
public function isRecaptchaEnabled() : bool {
|
||||||
return $this->recaptchaEnabled;
|
return $this->recaptchaEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRecaptchaSiteKey() {
|
public function getRecaptchaSiteKey() : string {
|
||||||
return $this->recaptchaPublicKey;
|
return $this->recaptchaPublicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRecaptchaSecretKey() {
|
public function getRecaptchaSecretKey() : string {
|
||||||
return $this->recaptchaPrivateKey;
|
return $this->recaptchaPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isRegistrationAllowed() : bool {
|
||||||
|
return $this->registrationAllowed;
|
||||||
|
}
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ class UpdateStrategy extends Strategy {
|
|||||||
private array $values;
|
private array $values;
|
||||||
private array $conflictingColumns;
|
private array $conflictingColumns;
|
||||||
|
|
||||||
public function __construct($conflictingColumns, $values) {
|
public function __construct(array $conflictingColumns, array $values) {
|
||||||
$this->conflictingColumns = $conflictingColumns;
|
$this->conflictingColumns = $conflictingColumns;
|
||||||
$this->values = $values;
|
$this->values = $values;
|
||||||
}
|
}
|
||||||
|
8
js/admin.min.js
vendored
8
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
@ -104,6 +104,14 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendTestMail(receiver) {
|
async sendTestMail(receiver) {
|
||||||
return this.apiCall("sendTestMail", { receiver: receiver });
|
return this.apiCall("mail/test", { receiver: receiver });
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchPermissions() {
|
||||||
|
return this.apiCall("permission/fetch");
|
||||||
|
}
|
||||||
|
|
||||||
|
async savePermissions(permissions) {
|
||||||
|
return this.apiCall("permission/save", { permissions: permissions });
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -209,8 +209,26 @@ export default class Overview extends React.Component {
|
|||||||
<li><b>Load Average</b>: { loadAvg }</li>
|
<li><b>Load Average</b>: { loadAvg }</li>
|
||||||
<li><b>Database</b>: { this.state.server["database"] }</li>
|
<li><b>Database</b>: { this.state.server["database"] }</li>
|
||||||
<li><b>Mail</b>: { this.state.server["mail"] === true
|
<li><b>Mail</b>: { this.state.server["mail"] === true
|
||||||
? <span>OK<Icon icon={""} className={"ml-2"}/></span>
|
? <span>
|
||||||
: <Link to={"/admin/settings"}>Not configured</Link>}</li>
|
OK
|
||||||
|
<Icon icon={"check-circle"} className={"ml-2 text-success"}/>
|
||||||
|
</span>
|
||||||
|
: <span>
|
||||||
|
<Link to={"/admin/settings"}>Not configured</Link>
|
||||||
|
<Icon icon={"times-circle"} className={"ml-2 text-danger"}/>
|
||||||
|
</span>}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Google reCaptcha</b>: { this.state.server["reCaptcha"] === true
|
||||||
|
? <span>
|
||||||
|
OK
|
||||||
|
<Icon icon={"check-circle"} className={"ml-2 text-success"}/>
|
||||||
|
</span>
|
||||||
|
: <span>
|
||||||
|
<Link to={"/admin/settings"}>Not configured</Link>
|
||||||
|
<Icon icon={"times-circle"} className={"ml-2 text-danger"}/>
|
||||||
|
</span>}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import Icon from "../elements/icon";
|
import Icon from "../elements/icon";
|
||||||
|
import Alert from "../elements/alert";
|
||||||
|
import ReactTooltip from "react-tooltip";
|
||||||
|
|
||||||
export default class PermissionSettings extends React.Component {
|
export default class PermissionSettings extends React.Component {
|
||||||
|
|
||||||
@ -10,11 +12,127 @@ export default class PermissionSettings extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
alerts: [],
|
alerts: [],
|
||||||
permissions: [],
|
permissions: [],
|
||||||
groups: {}
|
groups: {},
|
||||||
|
isSaving: false,
|
||||||
|
isResetting: false
|
||||||
|
};
|
||||||
|
|
||||||
|
this.parent = {
|
||||||
|
api: props.api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fetchPermissions()
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchPermissions() {
|
||||||
|
this.parent.api.fetchPermissions().then((res) => {
|
||||||
|
if (!res.success) {
|
||||||
|
let alerts = this.state.alerts.slice();
|
||||||
|
alerts.push({ message: res.msg, title: "Error fetching permissions" });
|
||||||
|
this.setState({...this.state, alerts: alerts, isResetting: false});
|
||||||
|
} else {
|
||||||
|
this.setState({...this.state, groups: res.groups, permissions: res.permissions, isResetting: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAlert(i) {
|
||||||
|
if (i >= 0 && i < this.state.alerts.length) {
|
||||||
|
let alerts = this.state.alerts.slice();
|
||||||
|
alerts.splice(i, 1);
|
||||||
|
this.setState({...this.state, alerts: alerts});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeMethod(e, index) {
|
||||||
|
if (index < 0 || index >= this.state.permissions.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = e.target.value;
|
||||||
|
let newPermissions = this.state.permissions.slice();
|
||||||
|
newPermissions[index].method = value;
|
||||||
|
this.setState({ ...this.state, permissions: newPermissions })
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
|
let alerts = [];
|
||||||
|
for (let i = 0; i < this.state.alerts.length; i++) {
|
||||||
|
alerts.push(<Alert key={"error-" + i} onClose={() => this.removeAlert(i)} {...this.state.alerts[i]}/>)
|
||||||
|
}
|
||||||
|
|
||||||
|
let th = [];
|
||||||
|
th.push(<th key={"th-method"}>Method</th>);
|
||||||
|
th.push(<th key={"th-everyone"} className={"text-center"}>Everyone</th>);
|
||||||
|
|
||||||
|
for (let groupId in this.state.groups) {
|
||||||
|
if (this.state.groups.hasOwnProperty(groupId)) {
|
||||||
|
let groupName = this.state.groups[groupId].name;
|
||||||
|
let groupColor = this.state.groups[groupId].color;
|
||||||
|
th.push(
|
||||||
|
<th key={"th-" + groupId} className={"text-center"}>
|
||||||
|
<span key={"group-" + groupId} className={"badge text-white"} style={{backgroundColor: groupColor}}>
|
||||||
|
{groupName}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tr = [];
|
||||||
|
for (let i = 0; i < this.state.permissions.length; i++) {
|
||||||
|
let permission = this.state.permissions[i];
|
||||||
|
let td = [];
|
||||||
|
|
||||||
|
if (permission.description) {
|
||||||
|
td.push(
|
||||||
|
<td>
|
||||||
|
<ReactTooltip id={"tooltip-" + i} />
|
||||||
|
{ permission.method }
|
||||||
|
<Icon icon={"info-circle"} className={"text-info float-right"}
|
||||||
|
data-tip={permission.description} data-place={"right"} data-type={"info"}
|
||||||
|
data-effect={"solid"} data-for={"tooltip-" + i} />
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
td.push(
|
||||||
|
<td>
|
||||||
|
<ReactTooltip id={"tooltip-" + i} />
|
||||||
|
<input type={"text"} maxLength={32} value={this.state.permissions[i].method}
|
||||||
|
onChange={(e) => this.onChangeMethod(e, i)} />
|
||||||
|
<Icon icon={"trash"} className={"text-danger float-right"}
|
||||||
|
data-tip={"Delete"} data-place={"right"} data-type={"error"}
|
||||||
|
data-effect={"solid"} data-for={"tooltip-" + i}
|
||||||
|
onClick={() => this.onDeletePermission(i)} style={{cursor: "pointer"}} />
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
td.push(
|
||||||
|
<td key={"td-everyone"} className={"text-center"}>
|
||||||
|
<input type={"checkbox"} checked={this.state.permissions[i].groups.length === 0}
|
||||||
|
onChange={(e) => this.onChangePermission(e, i)}/>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let groupId in this.state.groups) {
|
||||||
|
if (this.state.groups.hasOwnProperty(groupId)) {
|
||||||
|
groupId = parseInt(groupId);
|
||||||
|
td.push(
|
||||||
|
<td key={"td-" + groupId} className={"text-center"}>
|
||||||
|
<input type={"checkbox"} checked={this.state.permissions[i].groups.includes(groupId)}
|
||||||
|
onChange={(e) => this.onChangePermission(e, i, groupId)}/>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.push(<tr key={"permission-" + i}>{td}</tr>);
|
||||||
|
}
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div className="content-header">
|
<div className="content-header">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@ -35,15 +153,110 @@ export default class PermissionSettings extends React.Component {
|
|||||||
<div className={"content"}>
|
<div className={"content"}>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<div className={"col-lg-6 pl-5 pr-5"}>
|
<div className={"col-lg-6 pl-5 pr-5"}>
|
||||||
<form>
|
{alerts}
|
||||||
<Link to={"/admin/users"} className={"btn btn-info mt-2 mr-2"}>
|
<form onSubmit={(e) => e.preventDefault()}>
|
||||||
<Icon icon={"arrow-left"}/>
|
<table className={"table table-bordered table-hover dataTable dtr-inline"}>
|
||||||
Back
|
<thead>
|
||||||
</Link>
|
<tr role={"row"}>
|
||||||
|
{th}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{tr}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div className={"mt-2"}>
|
||||||
|
<Link to={"/admin/users"} className={"btn btn-primary"}>
|
||||||
|
<Icon icon={"arrow-left"}/>
|
||||||
|
Back
|
||||||
|
</Link>
|
||||||
|
<button className={"btn btn-info ml-2"} onClick={() => this.onAddPermission()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||||
|
<Icon icon={"plus"}/> Add new Permission
|
||||||
|
</button>
|
||||||
|
<button className={"btn btn-secondary ml-2"} onClick={() => this.onResetPermissions()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||||
|
{ this.state.isResetting ? <span>Resetting <Icon icon={"circle-notch"}/></span> : "Reset" }
|
||||||
|
</button>
|
||||||
|
<button className={"btn btn-success ml-2"} onClick={() => this.onSavePermissions()} disabled={this.state.isResetting || this.state.isSaving}>
|
||||||
|
{ this.state.isSaving ? <span>Saving <Icon icon={"circle-notch"}/></span> : "Save" }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAddPermission() {
|
||||||
|
let newPermissions = this.state.permissions.slice();
|
||||||
|
newPermissions.push({ method: "", groups: [], description: null });
|
||||||
|
this.setState({ ...this.state, permissions: newPermissions })
|
||||||
|
}
|
||||||
|
|
||||||
|
onResetPermissions() {
|
||||||
|
this.setState({ ...this.state, isResetting: true });
|
||||||
|
this.fetchPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
onSavePermissions() {
|
||||||
|
this.setState({ ...this.state, isSaving: true });
|
||||||
|
|
||||||
|
let permissions = [];
|
||||||
|
for (let i = 0; i < this.state.permissions.length; i++) {
|
||||||
|
let permission = this.state.permissions[i];
|
||||||
|
permissions.push({ method: permission.method, groups: permission.groups });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parent.api.savePermissions(permissions).then((res) => {
|
||||||
|
if (!res.success) {
|
||||||
|
let alerts = this.state.alerts.slice();
|
||||||
|
alerts.push({ message: res.msg, title: "Error saving permissions" });
|
||||||
|
this.setState({...this.state, alerts: alerts, isSaving: false});
|
||||||
|
} else {
|
||||||
|
this.setState({...this.state, isSaving: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeletePermission(index) {
|
||||||
|
if (index < 0 || index >= this.state.permissions.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newPermissions = this.state.permissions.slice();
|
||||||
|
newPermissions.splice(index, 1);
|
||||||
|
this.setState({ ...this.state, permissions: newPermissions })
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangePermission(event, index, group = null) {
|
||||||
|
if (index < 0 || index >= this.state.permissions.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isChecked = event.target.checked;
|
||||||
|
let newPermissions = this.state.permissions.slice();
|
||||||
|
if (group === null) {
|
||||||
|
if (isChecked) {
|
||||||
|
newPermissions[index].groups = [];
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isChecked && !newPermissions[index].groups.includes(group)) {
|
||||||
|
newPermissions[index].groups.push(group);
|
||||||
|
} else if(!isChecked) {
|
||||||
|
let indexOf = newPermissions[index].groups.indexOf(group);
|
||||||
|
if (indexOf !== -1) {
|
||||||
|
newPermissions[index].groups.splice(indexOf, 1);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ ...this.state, permissions: newPermissions })
|
||||||
|
}
|
||||||
};
|
};
|
@ -78,6 +78,7 @@ export default class Settings extends React.Component {
|
|||||||
return this.state.general.keys.includes(key)
|
return this.state.general.keys.includes(key)
|
||||||
|| this.state.mail.keys.includes(key)
|
|| this.state.mail.keys.includes(key)
|
||||||
|| this.state.messages.keys.includes(key)
|
|| this.state.messages.keys.includes(key)
|
||||||
|
|| this.state.recaptcha.keys.includes(key)
|
||||||
|| this.hiddenKeys.includes(key);
|
|| this.hiddenKeys.includes(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user