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) | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN); | ||||
|       $this->groupCount = 0; | ||||
|     } | ||||
| 
 | ||||
| @ -116,9 +114,6 @@ namespace Api\Groups { | ||||
|         'name' => new StringType('name', 32), | ||||
|         'color' => new StringType('color', 10), | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
| @ -165,9 +160,6 @@ namespace Api\Groups { | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'uid' => new Parameter('uid', Parameter::TYPE_INT) | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     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), | ||||
|       )); | ||||
|       $this->isPublic = false; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     private function checkUser($userId) { | ||||
|  | ||||
| @ -18,7 +18,11 @@ namespace Api\Permission { | ||||
|   use Api\Parameter\Parameter; | ||||
|   use Api\Parameter\StringType; | ||||
|   use Api\PermissionAPI; | ||||
|   use Driver\SQL\Column\Column; | ||||
|   use Driver\SQL\Condition\Compare; | ||||
|   use Driver\SQL\Condition\CondIn; | ||||
|   use Driver\SQL\Condition\CondNot; | ||||
|   use Driver\SQL\Strategy\UpdateStrategy; | ||||
|   use Objects\User; | ||||
| 
 | ||||
|   class Check extends PermissionAPI { | ||||
| @ -57,6 +61,7 @@ namespace Api\Permission { | ||||
|         } | ||||
| 
 | ||||
|         if (!$this->user->isLoggedIn() || empty(array_intersect($groups, array_keys($this->user->getGroups())))) { | ||||
|           header('HTTP 1.1 401 Unauthorized'); | ||||
|           return $this->createError("Permission denied."); | ||||
|         } | ||||
|       } | ||||
| @ -75,7 +80,7 @@ namespace Api\Permission { | ||||
| 
 | ||||
|     private function fetchGroups() { | ||||
|       $sql = $this->user->getSQL(); | ||||
|       $res = $sql->select("uid", "name") | ||||
|       $res = $sql->select("uid", "name", "color") | ||||
|         ->from("Group") | ||||
|         ->orderBy("uid") | ||||
|         ->ascending() | ||||
| @ -89,7 +94,8 @@ namespace Api\Permission { | ||||
|         foreach($res as $row) { | ||||
|           $groupId = $row["uid"]; | ||||
|           $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(); | ||||
|       $res = $sql->select("method", "groups") | ||||
|       $res = $sql->select("method", "groups", "description") | ||||
|         ->from("ApiPermission") | ||||
|         ->execute(); | ||||
| 
 | ||||
| @ -121,8 +127,13 @@ namespace Api\Permission { | ||||
|         $permissions = array(); | ||||
|         foreach ($res as $row) { | ||||
|           $method = $row["method"]; | ||||
|           $description = $row["description"]; | ||||
|           $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["groups"] = $this->groups; | ||||
| @ -149,7 +160,52 @@ namespace Api\Permission { | ||||
|         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; | ||||
|     } | ||||
|  | ||||
| @ -16,7 +16,6 @@ class Request { | ||||
|   protected bool $variableParamCount; | ||||
|   protected bool $isDisabled; | ||||
|   protected bool $apiKeyAllowed; | ||||
|   protected array $requiredGroup; | ||||
|   protected bool $csrfTokenRequired; | ||||
| 
 | ||||
|   private array $aDefaultParams; | ||||
| @ -36,7 +35,6 @@ class Request { | ||||
|     $this->variableParamCount = false; | ||||
|     $this->apiKeyAllowed = true; | ||||
|     $this->allowedMethods = array("GET", "POST"); | ||||
|     $this->requiredGroup = array(); | ||||
|     $this->lastError = ""; | ||||
|     $this->csrfTokenRequired = true; | ||||
|   } | ||||
| @ -54,15 +52,13 @@ class Request { | ||||
| 
 | ||||
|       $isEmpty = (is_string($value) || is_array($value)) && empty($value); | ||||
|       if(!$param->optional && (is_null($value) || $isEmpty)) { | ||||
|         $this->lastError = 'Missing parameter: ' . $name; | ||||
|         return false; | ||||
|         return $this->createError("Missing parameter: $name"); | ||||
|       } | ||||
| 
 | ||||
|       if(!is_null($value) && !$isEmpty) { | ||||
|         if(!$param->parseParam($value)) { | ||||
|           $value = print_r($value, true); | ||||
|           $this->lastError = "Invalid Type for parameter: $name '$value' (Required: " . $param->getTypeName() . ")"; | ||||
|           return false; | ||||
|           return $this->createError("Invalid Type for parameter: $name '$value' (Required: " . $param->getTypeName() . ")"); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| @ -135,9 +131,10 @@ class Request { | ||||
|           header('HTTP 1.1 401 Unauthorized'); | ||||
|           return false; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // CSRF Token
 | ||||
|         if($this->csrfTokenRequired && !$apiKeyAuthorized) { | ||||
|       if($this->csrfTokenRequired && $this->user->isLoggedIn()) { | ||||
|         // csrf token required + external call
 | ||||
|         // 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) { | ||||
| @ -146,15 +143,13 @@ class Request { | ||||
|           return false; | ||||
|         } | ||||
|       } | ||||
|       } | ||||
| 
 | ||||
|       // Check for permission
 | ||||
|       if (!($this instanceof PermissionAPI)) { | ||||
|       if (!($this instanceof \Api\Permission\Save)) { | ||||
|         $req = new \Api\Permission\Check($this->user); | ||||
|         $this->success = $req->execute(array("method" => $this->getMethod())); | ||||
|         $this->lastError = $req->getLastError(); | ||||
|         if (!$this->success) { | ||||
|           header('HTTP 1.1 401 Unauthorized'); | ||||
|           return false; | ||||
|         } | ||||
|       } | ||||
|  | ||||
| @ -32,8 +32,6 @@ namespace Api\Routes { | ||||
| 
 | ||||
|   public function __construct($user, $externalCall = false) { | ||||
|     parent::__construct($user, $externalCall, array()); | ||||
|     $this->loginRequired = true; | ||||
|     $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|   } | ||||
| 
 | ||||
|   public function execute($values = array()) { | ||||
| @ -133,9 +131,6 @@ namespace Api\Routes { | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'routes' => new Parameter('routes',Parameter::TYPE_ARRAY, false) | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     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) { | ||||
|       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()) { | ||||
| @ -73,9 +70,6 @@ namespace Api\Settings { | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'settings' => new Parameter('settings', Parameter::TYPE_ARRAY) | ||||
|       )); | ||||
| 
 | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|       $this->loginRequired = true; | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
|  | ||||
| @ -7,11 +7,11 @@ use Driver\SQL\Condition\CondBool; | ||||
| 
 | ||||
| class Stats extends Request { | ||||
| 
 | ||||
|   private bool $mailConfigured; | ||||
|   private bool $recaptchaConfigured; | ||||
| 
 | ||||
|   public function __construct($user, $externalCall = false) { | ||||
|     parent::__construct($user, $externalCall, array()); | ||||
| 
 | ||||
|     $this->loginRequired = true; | ||||
|     $this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN); | ||||
|   } | ||||
| 
 | ||||
|   private function getUserCount() { | ||||
| @ -67,12 +67,15 @@ class Stats extends Request { | ||||
|     return $visitors; | ||||
|   } | ||||
| 
 | ||||
|   private function isMailConfigured() { | ||||
|   private function checkSettings() { | ||||
|     $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) { | ||||
|       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; | ||||
| @ -95,8 +98,7 @@ class Stats extends Request { | ||||
|       $loadAvg = sys_getloadavg(); | ||||
|     } | ||||
| 
 | ||||
|     $mailConfigured = $this->isMailConfigured(); | ||||
|     if (!$this->success) { | ||||
|     if (!$this->checkSettings()) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
| @ -109,7 +111,8 @@ class Stats extends Request { | ||||
|       "memory_usage" => memory_get_usage(), | ||||
|       "load_avg" => $loadAvg, | ||||
|       "database" => $this->user->getSQL()->getStatus(), | ||||
|       "mail" => $mailConfigured | ||||
|       "mail" => $this->mailConfigured, | ||||
|       "reCaptcha" => $this->recaptchaConfigured | ||||
|     ); | ||||
| 
 | ||||
|     return $this->success; | ||||
|  | ||||
| @ -118,7 +118,6 @@ namespace Api\User { | ||||
| 
 | ||||
|   use Api\Parameter\Parameter; | ||||
|   use Api\Parameter\StringType; | ||||
|   use Api\SendMail; | ||||
|   use Api\UserAPI; | ||||
|   use Api\VerifyCaptcha; | ||||
|   use DateTime; | ||||
| @ -137,7 +136,6 @@ namespace Api\User { | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
| @ -179,15 +177,10 @@ namespace Api\User { | ||||
|     private int $userCount; | ||||
| 
 | ||||
|     public function __construct($user, $externalCall = false) { | ||||
| 
 | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'page' => new Parameter('page', Parameter::TYPE_INT, true, 1), | ||||
|         '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() { | ||||
| @ -297,13 +290,9 @@ namespace Api\User { | ||||
|   class Get extends UserAPI { | ||||
| 
 | ||||
|     public function __construct($user, $externalCall = false) { | ||||
| 
 | ||||
|       parent::__construct($user, $externalCall, array( | ||||
|         'id' => new Parameter('id', Parameter::TYPE_INT) | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
| @ -373,7 +362,6 @@ namespace Api\User { | ||||
|       )); | ||||
| 
 | ||||
|       $this->loginRequired = true; | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|     } | ||||
| 
 | ||||
|     public function execute($values = array()) { | ||||
| @ -418,7 +406,7 @@ namespace Api\User { | ||||
|             $body = str_replace("{{{$key}}}", $value, $body); | ||||
|           } | ||||
| 
 | ||||
|           $request = new SendMail($this->user); | ||||
|           $request = new \Api\Mail\Send($this->user); | ||||
|           $this->success = $request->execute(array( | ||||
|             "to" => $email, | ||||
|             "subject" => "[$siteName] Account Invitation", | ||||
| @ -560,18 +548,6 @@ namespace Api\User { | ||||
|       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()) { | ||||
|       if (!parent::execute($values)) { | ||||
|         return false; | ||||
| @ -581,11 +557,7 @@ namespace Api\User { | ||||
|         return $this->createError(L('You are already logged in')); | ||||
|       } | ||||
| 
 | ||||
|       $registrationAllowed = $this->checkSettings(); | ||||
|       if (!$this->success) { | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       $registrationAllowed = $this->user->getConfiguration()->getSettings()->isRegistrationAllowed(); | ||||
|       if(!$registrationAllowed) { | ||||
|         return $this->createError("User Registration is not enabled."); | ||||
|       } | ||||
| @ -640,7 +612,7 @@ namespace Api\User { | ||||
|           $body = str_replace("{{{$key}}}", $value, $body); | ||||
|         } | ||||
| 
 | ||||
|         $request = new SendMail($this->user); | ||||
|         $request = new \Api\Mail\Send($this->user); | ||||
|         $this->success = $request->execute(array( | ||||
|             "to" => $email, | ||||
|             "subject" => "[$siteName] E-Mail Confirmation", | ||||
| @ -696,7 +668,6 @@ namespace Api\User { | ||||
|         'groups' => new Parameter('groups', Parameter::TYPE_ARRAY, true, NULL), | ||||
|       )); | ||||
| 
 | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|       $this->loginRequired = true; | ||||
|     } | ||||
| 
 | ||||
| @ -786,7 +757,6 @@ namespace Api\User { | ||||
|         'id' => new Parameter('id', Parameter::TYPE_INT) | ||||
|       )); | ||||
| 
 | ||||
|       $this->requiredGroup = array(USER_GROUP_ADMIN); | ||||
|       $this->loginRequired = true; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -174,39 +174,30 @@ class CreateDatabase { | ||||
|     $queries[] = $sql->createTable("ApiPermission") | ||||
|       ->addString("method", 32) | ||||
|       ->addJson("groups", true, '[]') | ||||
|       ->addString("description", 128, false, "") | ||||
|       ->primaryKey("method"); | ||||
| 
 | ||||
|     $queries[] = $sql->insert("ApiPermission", array("method", "groups")) | ||||
|       ->addRow("ApiKey/create", array()) | ||||
|       ->addRow("ApiKey/fetch", array()) | ||||
|       ->addRow("ApiKey/refresh", array()) | ||||
|       ->addRow("ApiKey/revoke", array()) | ||||
|       ->addRow("Contact/request", array()) | ||||
|       ->addRow("Groups/fetch", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN)) | ||||
|       ->addRow("Groups/create", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Groups/delete", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Language/get", array()) | ||||
|       ->addRow("Language/set", array()) | ||||
|       ->addRow("Notifications/create", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Notifications/fetch", array()) | ||||
|       ->addRow("Notifications/seen", array()) | ||||
|       ->addRow("Routes/fetch", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Routes/save", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("sendTestMail", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN)) | ||||
|       ->addRow("Settings/get", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Settings/set", array(USER_GROUP_ADMIN)) | ||||
|       ->addRow("Stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT)) | ||||
|       ->addRow("User/create", array(USER_GROUP_ADMIN)) | ||||
|       ->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)); | ||||
|     $queries[] = $sql->insert("ApiPermission", array("method", "groups", "description")) | ||||
|       ->addRow("ApiKey/create", array(), "Allows users to create API-Keys for themselves") | ||||
|       ->addRow("ApiKey/fetch", array(), "Allows users to list their API-Keys") | ||||
|       ->addRow("ApiKey/refresh", array(), "Allows users to refresh their API-Keys") | ||||
|       ->addRow("ApiKey/revoke", array(), "Allows users to revoke their API-Keys") | ||||
|       ->addRow("Groups/fetch", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to list all available groups") | ||||
|       ->addRow("Groups/create", array(USER_GROUP_ADMIN), "Allows users to create a new groups") | ||||
|       ->addRow("Groups/delete", array(USER_GROUP_ADMIN), "Allows users to delete a group") | ||||
|       ->addRow("Routes/fetch", array(USER_GROUP_ADMIN), "Allows users to list all configured routes") | ||||
|       ->addRow("Routes/save", array(USER_GROUP_ADMIN), "Allows users to create, delete and modify routes") | ||||
|       ->addRow("Mail/test", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to send a test email to a given address") | ||||
|       ->addRow("Settings/get", array(USER_GROUP_ADMIN), "Allows users to fetch server settings") | ||||
|       ->addRow("Settings/set", array(USER_GROUP_ADMIN), "Allows users create, delete or modify server settings") | ||||
|       ->addRow("Stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to fetch server stats") | ||||
|       ->addRow("User/create", array(USER_GROUP_ADMIN), "Allows users to create a new user, email address does not need to be confirmed") | ||||
|       ->addRow("User/fetch", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to list all registered users") | ||||
|       ->addRow("User/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to get information about a single user") | ||||
|       ->addRow("User/invite", array(USER_GROUP_ADMIN), "Allows users to create a new user and send them an invitation link") | ||||
|       ->addRow("User/edit", array(USER_GROUP_ADMIN), "Allows users to edit details and group memberships of any user") | ||||
|       ->addRow("User/delete", array(USER_GROUP_ADMIN), "Allows users to delete any other user") | ||||
|       ->addRow("Permission/fetch", array(USER_GROUP_ADMIN), "Allows users to list all API permissions"); | ||||
| 
 | ||||
|     return $queries; | ||||
|   } | ||||
|  | ||||
| @ -81,23 +81,27 @@ class Settings { | ||||
|       ->addRow("recaptcha_private_key", $this->recaptchaPrivateKey, true, false); | ||||
|   } | ||||
| 
 | ||||
|   public function getSiteName() { | ||||
|   public function getSiteName() : string { | ||||
|     return $this->siteName; | ||||
|   } | ||||
| 
 | ||||
|   public function getBaseUrl() { | ||||
|   public function getBaseUrl() : string { | ||||
|     return $this->baseUrl; | ||||
|   } | ||||
| 
 | ||||
|   public function isRecaptchaEnabled() { | ||||
|   public function isRecaptchaEnabled() : bool { | ||||
|     return $this->recaptchaEnabled; | ||||
|   } | ||||
| 
 | ||||
|   public function getRecaptchaSiteKey() { | ||||
|   public function getRecaptchaSiteKey() : string { | ||||
|     return $this->recaptchaPublicKey; | ||||
|   } | ||||
| 
 | ||||
|   public function getRecaptchaSecretKey() { | ||||
|   public function getRecaptchaSecretKey() : string { | ||||
|     return $this->recaptchaPrivateKey; | ||||
|   } | ||||
| 
 | ||||
|   public function isRegistrationAllowed() : bool { | ||||
|     return $this->registrationAllowed; | ||||
|   } | ||||
| } | ||||
| @ -7,7 +7,7 @@ class UpdateStrategy extends Strategy { | ||||
|   private array $values; | ||||
|   private array $conflictingColumns; | ||||
| 
 | ||||
|   public function __construct($conflictingColumns, $values) { | ||||
|   public function __construct(array $conflictingColumns, array $values) { | ||||
|     $this->conflictingColumns = $conflictingColumns; | ||||
|     $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) { | ||||
|         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>Database</b>: { this.state.server["database"]  }</li> | ||||
|                                         <li><b>Mail</b>: { this.state.server["mail"] === true | ||||
|                                             ?  <span>OK<Icon icon={""} className={"ml-2"}/></span> | ||||
|                                             :  <Link to={"/admin/settings"}>Not configured</Link>}</li> | ||||
|                                             ? <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> | ||||
|                                         <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> | ||||
|                                 </div> | ||||
|                             </Collapse> | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| import * as React from "react"; | ||||
| import {Link} from "react-router-dom"; | ||||
| import Icon from "../elements/icon"; | ||||
| import Alert from "../elements/alert"; | ||||
| import ReactTooltip from "react-tooltip"; | ||||
| 
 | ||||
| export default class PermissionSettings extends React.Component { | ||||
| 
 | ||||
| @ -10,11 +12,127 @@ export default class PermissionSettings extends React.Component { | ||||
|         this.state = { | ||||
|             alerts: [], | ||||
|             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() { | ||||
| 
 | ||||
|         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 <> | ||||
|             <div className="content-header"> | ||||
|                 <div className="container-fluid"> | ||||
| @ -35,15 +153,110 @@ export default class PermissionSettings extends React.Component { | ||||
|             <div className={"content"}> | ||||
|                 <div className={"row"}> | ||||
|                     <div className={"col-lg-6 pl-5 pr-5"}> | ||||
|                         <form> | ||||
|                             <Link to={"/admin/users"} className={"btn btn-info mt-2 mr-2"}> | ||||
|                         {alerts} | ||||
|                         <form onSubmit={(e) => e.preventDefault()}> | ||||
|                             <table className={"table table-bordered table-hover dataTable dtr-inline"}> | ||||
|                                 <thead> | ||||
|                                     <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> | ||||
|                     </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) | ||||
|             || this.state.mail.keys.includes(key) | ||||
|             || this.state.messages.keys.includes(key) | ||||
|             || this.state.recaptcha.keys.includes(key) | ||||
|             || this.hiddenKeys.includes(key); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user