From 7ebefccb28b048d56058af4d1487298fa122b566 Mon Sep 17 00:00:00 2001 From: Collin Date: Thu, 19 Sep 2024 08:32:56 +0000 Subject: [PATCH] Commenting and stuff --- build/build-phar.php | 2 + src/LonaDB/Logger.php | 78 ++++++++++++++---------- src/LonaDB/LonaDB.php | 58 ++++++++++++++++-- src/LonaDB/Plugins/PluginBase.php | 10 ++- src/LonaDB/Plugins/PluginManager.php | 4 +- src/LonaDB/Server.php | 67 +++++++++++++++----- src/LonaDB/Tables/Table.php | 3 + src/LonaDB/Users/UserManager.php | 91 +++++++++++++++++++--------- 8 files changed, 231 insertions(+), 82 deletions(-) diff --git a/build/build-phar.php b/build/build-phar.php index b26cd5e..3ba6951 100644 --- a/build/build-phar.php +++ b/build/build-phar.php @@ -78,6 +78,8 @@ try { builderLog("[RUN] Generating run script"); file_put_contents("./build/run-phar.sh", 'cd '.$path.' ; printf "test\n" | php -dphar.readonly=0 '.$filename.'-'.$version.'.phar'); + file_put_contents("./build/run-phar-pm2.sh", 'cd release ; printf "test\n" | php -dphar.readonly=0 '.$filename.'-'.$version.'.phar'); + file_put_contents("./build/run-phar-debug-pm2.sh", 'cd debug ; printf "test\n" | php -dphar.readonly=0 '.$filename.'-'.$version.'.phar'); builderLog("[RUN] Adding Permissions to run script"); exec("chmod 777 ./build/run-phar.sh"); diff --git a/src/LonaDB/Logger.php b/src/LonaDB/Logger.php index 4650717..9cf4c30 100644 --- a/src/LonaDB/Logger.php +++ b/src/LonaDB/Logger.php @@ -2,41 +2,75 @@ namespace LonaDB; +//Load autoload from composer require 'vendor/autoload.php'; + +//Load Main file use LonaDB\LonaDB; class Logger{ + //Create all variables private $LogFile; private string $infoCache = ""; - private LonaDB $LonaDB; private bool $Start = false; + private LonaDB $LonaDB; + public function __construct(LonaDB $lonaDB){ $this->LonaDB = $lonaDB; } - private function log(string $message) : void { - echo($message."\e[0m"); + private function log(string $message, string $color = "") : void { + echo($color.$message."\e[0m"); + //Write logs to file if enabled if($this->LonaDB->config["logging"]) fwrite($this->LogFile, $message); } public function LoadLogger() : void { + //Create file instance if logging to file is enabled if($this->LonaDB->config["logging"]) $this->LogFile = fopen('log.txt','a'); } + public function Start($msg) : void { + //Check if the Startup message has already been sent + if(!$this->Start){ + //Declare that the Startup message has been sent + $this->Start = true; + + //Send the Startup message + $log = date("Y-m-d h:i:s")." [Startup] ".$msg."\n"; + $this->log($log); + } + } + + public function InfoCache($msg) : void { + //Log InfoCache into the terminal + $log = date("Y-m-d h:i:s")." [INFO] ".$msg."\n"; + echo($log); + + //Add message to the InfoCache variable + $this->infoCache = $this->infoCache . $log; + } + + public function DropCache() : void { + //Drop all of InfoCache's content into the log file if enabled + if($this->LonaDB->config["logging"]) fwrite($this->LogFile, $this->infoCache); + } + + //Logger funcitons public function Warning($msg) : void { - $log = "\033[33m" . date("Y-m-d h:i:s")." [WARNING] ".$msg."\n"; - $this->log($log); + $log = date("Y-m-d h:i:s")." [WARNING] ".$msg."\n"; + $this->log($log, "\033[33m"); } public function Error($msg) : void { - $log = "\033[31m" . date("Y-m-d h:i:s")." [ERROR] ".$msg."\n"; - $this->log($log); + $log = date("Y-m-d h:i:s")." [ERROR] ".$msg."\n"; + $this->log($log, "\033[31m"); } public function Create($msg) : void { - $log = "\033[32m" . date("Y-m-d h:i:s")." [CREATE] ".$msg."\n"; - $this->log($log); + $log = date("Y-m-d h:i:s")." [CREATE] ".$msg."\n"; + $this->log($log, "\033[32m"); } public function Load($msg) : void { @@ -45,8 +79,8 @@ class Logger{ } public function Info($msg) : void { - $log = "\033[34m" . date("Y-m-d h:i:s")." [INFO] ".$msg."\n"; - $this->log($log); + $log = date("Y-m-d h:i:s")." [INFO] ".$msg."\n"; + $this->log($log, "\033[34m"); } public function Table($msg) : void { @@ -60,25 +94,7 @@ class Logger{ } public function Plugin($name, $msg) : void { - $log = "\033[35m" . date("Y-m-d h:i:s")." [Plugin] ".$name.": ".$msg."\n"; - $this->log($log); - } - - public function Start($msg) : void { - if(!$this->Start){ - $this->Start = true; - $log = date("Y-m-d h:i:s")." [Startup] ".$msg."\n"; - $this->log($log); - } - } - - public function InfoCache($msg) : void { - $log = date("Y-m-d h:i:s")." [INFO] ".$msg."\n"; - echo($log); - $this->infoCache = $this->infoCache.$log; - } - - public function DropCache() : void { - if($this->LonaDB->config["logging"]) fwrite($this->LogFile, $this->infoCache); + $log = date("Y-m-d h:i:s")." [Plugin] ".$name.": ".$msg."\n"; + $this->log($log,"\033[35m"); } } \ No newline at end of file diff --git a/src/LonaDB/LonaDB.php b/src/LonaDB/LonaDB.php index 1f377bf..35af61e 100644 --- a/src/LonaDB/LonaDB.php +++ b/src/LonaDB/LonaDB.php @@ -2,9 +2,13 @@ namespace LonaDB; +//Encryption/decryption define('AES_256_CBC', 'aes-256-cbc'); +//Load autoload from composer require 'vendor/autoload.php'; + +//Load Server, Logger and Managers use LonaDB\Server; use LonaDB\Logger; use LonaDB\Tables\TableManager; @@ -13,6 +17,7 @@ use LonaDB\Functions\FunctionManager; use LonaDB\Plugins\PluginManager; class LonaDB { + //Create all variables public array $config; public bool $Running = false; public string $EncryptionKey; @@ -25,41 +30,62 @@ class LonaDB { public PluginManager $PluginManager; public function __construct(string $key) { + //EncryptionKey is used to decrypt the configuration.lona file $this->EncryptionKey = $key; + //Create an instance of the Logger $this->Logger = new Logger($this); + //Run variable, used to know if the configuration was decrypted successfully $run = false; try{ echo chr(27).chr(91).'H'.chr(27).chr(91).'J'; error_reporting(E_ERROR | E_PARSE); - + + $this->Logger->InfoCache("LonaDB v4.6.0"); $this->Logger->InfoCache("Looking for config."); + //Create an empty configuration.lona if it doesn't exist. file_exists gave an error because we run LonaDB as a phar. file_put_contents("configuration.lona", file_get_contents("configuration.lona")); + //If the file didn't exist before, run setup if(file_get_contents("configuration.lona") === "") $this->setup(); - + //If the file did exist before, decrypt it else{ + //Split the encrypted content from the IV $parts = explode(':', file_get_contents("./configuration.lona")); + //Decrypt the config using the EncryptionKey and IV $decrypted = openssl_decrypt($parts[0], AES_256_CBC, $this->EncryptionKey, 0, base64_decode($parts[1])); + + //If the given EncryptionKey didn't work, throw an error and exit if(!json_decode($decrypted, true)) { echo "Encryption Key does not match the existing Configuration file. Exiting.\n"; - }else $run = true; + } + //Else, start the DB server + else $run = true; } + //If the configuration was decrypted successfully if($run){ $this->Logger->InfoCache("Loading config."); + //Split encrypted from IV $parts = explode(':', file_get_contents("./configuration.lona")); + //Decrypt using EncryptionKey and IV $decrypted = openssl_decrypt($parts[0], AES_256_CBC, $this->EncryptionKey, 0, base64_decode($parts[1])); + //Load the config $this->config = json_decode($decrypted, true); $this->Logger->InfoCache("Checking config."); + //Check if the configuration is missing something if(!$this->config["port"] || !$this->config["address"] || !$this->config["encryptionKey"] || !$this->config["root"]) { + //Configuration is missing a variable => Setup $this->setup(); } + //Check if logging to a file is enabled, if it is, write logs to the file $this->Logger->LoadLogger(); + //Dop the chached logs to the file (if enabled) $this->Logger->DropCache(); + //Initialize Manaers $this->Logger->Info("Loading TableManager class."); $this->TableManager = new TableManager($this); $this->Logger->Info("Loading UserManager class."); @@ -69,7 +95,10 @@ class LonaDB { $this->Logger->Info("Loading PluginManager class."); $this->PluginManager = new PluginManager($this); + //If the server is already runnning + //This is needed because in some ocasions we had the server start twice, stopping the first one and throwing an error if(!$this->Running){ + //Initialize server $this->Logger->Info("Loading Server class."); $this->Server = new Server($this); } @@ -80,35 +109,45 @@ class LonaDB { } } + //Tell the PluginManager to load all plugins public function LoadPlugins() : void { + //Check if the Plugins have already been loaded if($this->PluginManager->Loaded) return; + //Load Plugins $this->PluginManager->LoadPlugins(); } + //Setup script private function setup() : void { $this->Logger->InfoCache("Invalid or missing config. Starting setup."); + + //Port echo "Database port:\n"; $portHandle = fopen ("php://stdin","r"); $port = intval(str_replace("\n", "", fgets($portHandle))); fclose($portHandle); + //IP echo "Database address:\n"; $addrHandle = fopen ("php://stdin","r"); $addr = fgets($addrHandle); fclose($addrHandle); - echo "Table encryption key:\n"; + //EncryptionKey for all data + echo "Data encryption key:\n"; $keyHandle = fopen ("php://stdin","r"); $key = fgets($keyHandle); fclose($keyHandle); + //Root password echo "Password for root user:\n"; $rootHandle = fopen ("php://stdin","r"); $root = fgets($rootHandle); fclose($rootHandle); - echo "Enable logging? (y/N):\n"; + //Logging to file + echo "Enable logging to a file? (y/N):\n"; $logHandle = fopen ("php://stdin","r"); $logAns = fgets($logHandle); fclose($logHandle); @@ -117,7 +156,9 @@ class LonaDB { $this->Logger->InfoCache("Saving config."); + //Create IV $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_256_CBC)); + //Put input into an array $save = array( "port" => $port, "address" => str_replace("\n","",$addr), @@ -126,21 +167,27 @@ class LonaDB { "root" => str_replace("\n","",$root) ); + //Encrypt config $encrypted = openssl_encrypt(json_encode($save), AES_256_CBC, $this->EncryptionKey, 0, $iv); + //Save to configuration.lona file_put_contents("./configuration.lona", $encrypted.":".base64_encode($iv)); } + //Stop script public function Stop() : void { echo chr(27).chr(91).'H'.chr(27).chr(91).'J'; echo "[Shutdown]\n"; echo "Killing threads...\n"; + //Stop the server $this->Server->Stop(); + //Kill plugin Threads $this->PluginManager->KillThreads(); echo "Done!\n"; exit(); } } +//Ask for the EncryptionKey echo "Encryption key:\n"; $keyHandle = fopen ("php://stdin","r"); $key = fgets($keyHandle); @@ -149,4 +196,5 @@ fclose($keyHandle); $encryptionKey = str_replace("\n","",$key); unset($key); +//Initialize LonaDB $run = new LonaDB($encryptionKey); \ No newline at end of file diff --git a/src/LonaDB/Plugins/PluginBase.php b/src/LonaDB/Plugins/PluginBase.php index 79ee860..68067a0 100644 --- a/src/LonaDB/Plugins/PluginBase.php +++ b/src/LonaDB/Plugins/PluginBase.php @@ -8,12 +8,14 @@ use LonaDB\Logger; require 'vendor/autoload.php'; class PluginBase{ - private string $Name; private LonaDB $LonaDB; + private string $Name; + private string $Version; - public function __construct(LonaDB $LonaDB, string $name) { + public function __construct(LonaDB $LonaDB, string $name, string $version) { $this->LonaDB = $LonaDB; $this->Name = $name; + $this->Version = $version; $this->GetLogger()->Load("Loading Plugin '" . $this->Name . "'"); } @@ -24,9 +26,11 @@ class PluginBase{ final public function GetLonaDB() : LonaDB { return $this->LonaDB; } + final public function GetLogger() : Logger { return $this->LonaDB->Logger; } + final public function GetName() : string { return $this->Name; } - final public function GetLogger() : Logger { return $this->LonaDB->Logger; } + final public function GetVersion() : string { return $this->Version; } //Events public function onTableCreate(string $executor, string $name) : void {} diff --git a/src/LonaDB/Plugins/PluginManager.php b/src/LonaDB/Plugins/PluginManager.php index 678555a..683c161 100644 --- a/src/LonaDB/Plugins/PluginManager.php +++ b/src/LonaDB/Plugins/PluginManager.php @@ -40,7 +40,7 @@ class PluginManager{ try{ $this->load_classphp($path, $phar); - eval("\$this->Plugins[\$conf['name']] = new " . $conf['main']['namespace'] . "\\" . $conf['main']['class'] . "(\$this->LonaDB, \$conf['name']);"); + eval("\$this->Plugins[\$conf['name']] = new " . $conf['main']['namespace'] . "\\" . $conf['main']['class'] . "(\$this->LonaDB, \$conf['name'], \$conf['version']);"); $pid = @ pcntl_fork(); if( $pid == -1 ) { @@ -86,7 +86,7 @@ class PluginManager{ $phar->stopBuffering(); } - eval("\$this->Plugins[\$conf['name']] = new " . $conf['main']['namespace'] . "\\" . $conf['main']['class'] . "(\$this->LonaDB, \$conf['name']);"); + eval("\$this->Plugins[\$conf['name']] = new " . $conf['main']['namespace'] . "\\" . $conf['main']['class'] . "(\$this->LonaDB, \$conf['name'], \$conf['version']);"); $pid = @ pcntl_fork(); if( $pid == -1 ) { diff --git a/src/LonaDB/Server.php b/src/LonaDB/Server.php index 4406130..4d291ae 100644 --- a/src/LonaDB/Server.php +++ b/src/LonaDB/Server.php @@ -2,41 +2,57 @@ namespace LonaDB; +//Load autoload from composer require 'vendor/autoload.php'; + +//Load Main file use LonaDB\LonaDB; class Server { + //Create all variables private array $config; - private LonaDB $LonaDB; + private array $actions = []; private string $address; private int $port; - private array $actions = []; private $socket; private bool $SocketRunning; + private LonaDB $LonaDB; + public function __construct(LonaDB $lonaDB) { $this->LonaDB = $lonaDB; + //Check if the Server is already running if($this->LonaDB->Running) return; + //Declare important variables $this->LonaDB->Running = true; $this->SocketRunning = false; $this->config = $lonaDB->config; + //IP and port for the TCP Socket $this->address = $this->config["address"]; $this->port = $this->config["port"]; + //Load all networking actions $this->loadActions(); + //Start TCP Socket $this->startSocket(); } private function loadActions() : void { + //Scan the Actions directory IN THE PHAR FILE $actionFiles = scandir(__DIR__ . "/Actions/"); + + //Loop through all action files foreach ($actionFiles as $file) { + //If file extension is "php" if (pathinfo($file, PATHINFO_EXTENSION) === 'php') { + //Set variable actionName to the file name without extension $actionName = pathinfo($file, PATHINFO_FILENAME); + //Load action file to the actions array $this->actions[$actionName] = require(__DIR__ . "/Actions/" . $file); $this->LonaDB->Logger->Info("Loaded Networking action from file '".$actionName."'"); } @@ -44,45 +60,55 @@ class Server { } public function startSocket() : void { + //Check if the socket is already running if($this->LonaDB->SocketRunning) return; + + //Initialize the socket $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1); + //Check if there was an error while initializing the socket if ($this->socket === false) { $this->LonaDB->Logger->Error("Failed to create socket: " . socket_strerror(socket_last_error())); return; } + //Try binding the socket to the desired IP and port if (!socket_bind($this->socket, $this->address, $this->port)) { $this->LonaDB->Logger->Error("Failed to bind socket: " . socket_strerror(socket_last_error())); return; } + //Try to listen for clients if (!socket_listen($this->socket)) { $this->LonaDB->Logger->Error("Failed to listen on socket: " . socket_strerror(socket_last_error())); return; } + //Tell the PluginManager to load the plugins $this->LonaDB->LoadPlugins(); - if($this->SocketRunning === false){ - $this->LonaDB->Logger->Start("Server running on port ".$this->port); - $this->SocketRunning = true; - } + $this->LonaDB->Logger->Start("Server running on port ".$this->port); + $this->SocketRunning = true; while (true) { + //Accept the connections $client = socket_accept($this->socket); + //If cannot accept connections if ($client === false) { $this->LonaDB->Logger->Error("Failed to accept client connection: " . socket_strerror(socket_last_error())); continue; } + //Read data form clients $data = socket_read($client, 1024); + //If cannot read data if ($data === false) { $this->LonaDB->Logger->Error("Failed to read data from client: " . socket_strerror(socket_last_error())); continue; } + //Handle data recieved from client $this->handleData($data, $client); } @@ -97,31 +123,43 @@ class Server { private function handleData(string $dataString, $client) : void { try { + //Convert data from JSON to PHP Array $data = json_decode($dataString, true); - if(!is_array($data)) return; - if(!array_key_exists('action', $data)) return; + //Check if the data has been converted successfully + if(!is_array($data)) return; + + //Check if action has been set + if(!array_key_exists('action', $data)) return; + + //Check if data contains a ProcessID + if (!$data['process']) { + $response = json_encode(["success" => false, "err" => "bad_process_id", "process" => $data['process']]); + socket_write($client, $response); + return; + } + //Create a hash from the ProcessID to get the encryption key for the password $key = hash('sha256', $data['process'], true); + //Split the encrypted password from the IV $parts = explode(':', $data['login']['password']); + //Get IV and ciphertext $iv = hex2bin($parts[0]); $ciphertext = hex2bin($parts[1]); + //Decrypt the password $password = openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); + //Try logging in with the username and decrypted password $login = $this->LonaDB->UserManager->CheckPassword($data['login']['name'], $password); + //Check if login was successfull if (!$login) { $response = json_encode(["success" => false, "err" => "login_error", "process" => $data['process']]); socket_write($client, $response); return; } - if (!$data['process']) { - $response = json_encode(["success" => false, "err" => "bad_process_id", "process" => $data['process']]); - socket_write($client, $response); - return; - } - + //Check if requested action exists if (!$this->actions[$data['action']]) { $response = json_encode(["success" => false, "err" => "action_not_found"]); socket_write($client, $response); @@ -129,6 +167,7 @@ class Server { } try { + //Run action $this->actions[$data['action']]->Run($this->LonaDB, $data, $client); } catch (Exception $e) { $this->LonaDB->Loggin->Error($e->getMessage()); diff --git a/src/LonaDB/Tables/Table.php b/src/LonaDB/Tables/Table.php index ac64476..21423b7 100644 --- a/src/LonaDB/Tables/Table.php +++ b/src/LonaDB/Tables/Table.php @@ -2,11 +2,14 @@ namespace LonaDB\Tables; +//Encryption/decryption define('AES_256_CBC', 'aes-256-cbc'); +//Load Main file use LonaDB\LonaDB; class Table{ + //Create all variables private string $file; private array $data; private array $permissions; diff --git a/src/LonaDB/Users/UserManager.php b/src/LonaDB/Users/UserManager.php index 6565b99..a2eb961 100644 --- a/src/LonaDB/Users/UserManager.php +++ b/src/LonaDB/Users/UserManager.php @@ -2,70 +2,93 @@ namespace LonaDB\Users; +//Encryption/decryption define('AES_256_CBC', 'aes-256-cbc'); +//Load autoload from composer require 'vendor/autoload.php'; + +//Load Main file use LonaDB\LonaDB; class UserManager{ - private LonaDB $LonaDB; + //Create all variables private array $Users; + private LonaDB $LonaDB; public function __construct(LonaDB $lonaDB){ $this->LonaDB = $lonaDB; - $this->Tables = array(); + //Create Array for users + $this->Users = array(); + //Create folder data if it doesn't exist if(!is_dir("data/")) mkdir("data/"); + //Create an empty Users.lona file if it doesn't exist file_put_contents("data/Users.lona", file_get_contents("data/Users.lona")); + //Check if the Users.lona file didn't exist before if(file_get_contents("data/Users.lona") === "") { + //Create an IV for encryption $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_256_CBC)); + //Create an empty Array $save = array(); + //Convert and decrypt the array $encrypted = openssl_encrypt(json_encode($save), AES_256_CBC, $this->LonaDB->config["encryptionKey"], 0, $iv); + //Save the array file_put_contents("./data/Users.lona", $encrypted.":".base64_encode($iv)); } + //Split the decrypted Users.lona from the IV $parts = explode(':', file_get_contents("./data/Users.lona")); + //Load the Users $this->Users = json_decode(openssl_decrypt($parts[0], AES_256_CBC, $this->LonaDB->config["encryptionKey"], 0, base64_decode($parts[1])), true); } public function CheckPassword(string $name = "", string $password = "") : bool { + //If username is root, check for the root password if($name === "root" && $password === $this->LonaDB->config["root"]) return true; - + //Check if the user exists if(!$this->Users[$name]) { return false; } - + //Check if the password is correct if($this->Users[$name]["password"] !== $password) return false; - + //All checks successfull return true; } public function CheckUser(string $name) : bool { + //Check if username is root if($name === "root") return true; + //Check if the user exists if(!$this->Users[$name]) return false; + //User does exist return true; } public function ListUsers() : array { + //Empty array for users & roles $users = []; - + //Loop through all Users foreach($this->Users as $name => $user){ + //Username => Role + //Example: Hymmel => Administrator $users[$name] = $this->GetRole($name); } - return $users; } public function CreateUser(string $name, string $password) : bool { + //If username is root, abort if($name === "root") return false; $this->LonaDB->Logger->User("Trying to create user '" . $name . "'"); - if($this->Users[$name]) { + //Check if there already is a user with that name + if($this->CheckUser($name)) { $this->LonaDB->Logger->Error("User '" . $name . "' already exists"); return false; } - + //Add user to the users array $this->Users[$name] = array( "role" => "User", "password" => $password, @@ -73,88 +96,102 @@ class UserManager{ "default" => true ] ); - $this->LonaDB->Logger->User("User '" . $name . "' has been created"); - + //Save users array to Users.lona $this->Save(); return true; } public function DeleteUser(string $name) : bool { + //If username is root, abort if($name === "root") return false; $this->LonaDB->Logger->User("Trying to delete user '" . $name . "'"); - - if(!$this->Users[$name]) { + //Check if user exists + if(!$this->CheckUser($name)) { $this->LonaDB->Logger->Error("User '" . $name . "' doesn't exist"); return false; } - + //Delete user from users array unset($this->Users[$name]); $this->LonaDB->Logger->User("Deleted user '" . $name . "'"); + //Save users array to Users.lona $this->Save(); return true; } public function SetRole(string $name, string $role) : bool { + //If username is root or desired role is Superuser, abort if($name === "root") return false; if($role === "Superuser") return false; - + //Check if user exists if(!$this->CheckUser($name)) return false; - + //Set user role $this->Users[$name]['role'] = $role; + //Save users array to Users.lona $this->Save(); return true; } - public function GetRole(string $name) : string { + public function GetRole(string $name) : mixed { + //Root is superuser if($name === "root") return "Superuser"; - if(!$this->CheckUser($name)) return ""; - + //Check if user exists + if(!$this->CheckUser($name)) return false; + //Deny normal users from being a Superuser -> Only root should be an Superuser if($this->Users[$name]['role'] === "Superuser") $this->Users[$name]['role'] = "User"; - + //Return user role return $this->Users[$name]['role']; } public function CheckPermission(string $name, string $permission, string $user = "") : bool { + //Check if user exists if(!$this->CheckUser($name)) return false; + //If user is an Administrator or Superuser, they are allowed to do anything if($this->GetRole($name) === "Administrator" || $this->GetRole($name) === "Superuser") return true; - + //Return user permission if(!$this->Users[$name]['permissions'][$permission]) return false; - return true; } public function GetPermissions(string $name) : array { + //If username is root, return an empty array -> Root is allowed to do anything if($name === "root") return []; + //Return the desires user's permissions as an array return $this->Users[$name]['permissions']; } public function AddPermission(string $name, string $permission) : bool { + //Check if username is root -> You cannot add permissions to root if($name === "root") return false; + //Check if user exists if(!$this->CheckUser($name)) return false; - + //Add the permission to the user $this->Users[$name]['permissions'][$permission] = true; $this->LonaDB->Logger->User("Added permission '" . $permission . "' to user '" . $name . "'"); - + //Save Users.lona $this->Save(); return true; } public function RemovePermission(string $name, string $permission) : bool { + //Check if username is root -> You cannot remove permissions from root if($name === "root") return false; + //Check if user exists if(!$this->CheckUser($name)) return false; - + //Remove the permission from the user unset($this->Users[$name]['permissions'][$permission]); $this->LonaDB->Logger->User("Removed permission '" . $permission . "' from user '" . $name . "'"); - + //Save Users.lona $this->Save(); return true; } public function Save() : void { + //Generate IV $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_256_CBC)); - + //Encrypt Users array $encrypted = openssl_encrypt(json_encode($this->Users), AES_256_CBC, $this->LonaDB->config["encryptionKey"], 0, $iv); + //Save the encrypted data + the IV to Users.lona file_put_contents("./data/Users.lona", $encrypted.":".base64_encode($iv)); } }