commit 43e6592bfa28ea1885e1fccc8615fb516939f308 Author: Collin Date: Fri Mar 15 09:13:20 2024 +0000 Initial upload diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80598f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +JavaScript/node_modules +Python/venv +Python/dist +Python/buildc +Python/lonadb_client.egg-info +token \ No newline at end of file diff --git a/JavaScript/Client.js b/JavaScript/Client.js new file mode 100644 index 0000000..9e425ac --- /dev/null +++ b/JavaScript/Client.js @@ -0,0 +1,245 @@ +const crypto = require('crypto'); + +class LonaDB { + constructor(host, port, name, password) { + this.host = host; + this.port = port; + this.name = name; + this.password = password; + } + + makeid(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz'; + let counter = 0; + + while (counter < length) { + result += characters[Math.floor(Math.random() * characters.length)]; + counter += 1; + } + + return result; + } + + sendRequest = async function(action, data) { + let net = require('net'); + let processID = this.makeid(5); + + let encryptionKey = crypto.createHash('sha256').update(processID).digest('base64'); + + let encryptedPassword = await this.encryptPassword(this.password, encryptionKey); + + let request = JSON.stringify({ + action, + login: { + name: this.name, + password: encryptedPassword + }, + process: processID, + ...data + }); + + return new Promise((resolve, reject) => { + let socket = net.createConnection({ + host: this.host, + port: this.port + }, () => { + socket.write(request); + }); + + let response = ''; + + socket.on('data', (chunk) => { + response += chunk; + }); + + socket.on('end', () => { + resolve(JSON.parse(response)); + }); + + socket.on('error', (err) => { + reject({ err: err.message }); + }); + }); + } + + + encryptPassword(password, key) { + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key, 'base64'), iv); + + let encrypted = cipher.update(password); + encrypted = Buffer.concat([encrypted, cipher.final()]); + + return iv.toString('hex') + ':' + encrypted.toString('hex'); + } + + createFunction(name, content) { + const data = { + "function": { + "name": name, + "content": content + } + }; + + return this.sendRequest("add_function", data); + } + + executeFunction(name) { + const data = { + "name": name + }; + + return this.sendRequest("execute_function", data); + } + + getTables(user) { + const data = { + user + }; + + return this.sendRequest('get_tables', data); + } + + getTableData(table) { + const data = { + table + }; + + return this.sendRequest('get_table_data', data); + } + + deleteTable(table) { + const data = { + table: { name: table } + }; + + return this.sendRequest('delete_table', data); + } + + createTable(table) { + const data = { + table: { name: table } + }; + + return this.sendRequest('create_table', data); + } + + set(table, name, value) { + const data = { + table: { name: table }, + variable: { + name: name, + value: value + } + }; + + return this.sendRequest('set_variable', data); + } + + delete(table, name) { + const data = { + table: { name: table }, + variable: { name: name } + }; + + return this.sendRequest('remove_variable', data); + } + + get(table, name) { + const data = { + table: { name: table }, + variable: { name: name } + }; + + return this.sendRequest('get_variable', data); + } + + getUsers() { + const data = {}; + return this.sendRequest('get_users', data); + } + + createUser(name, pass) { + const data = { + user: { + name: name, + password: pass + } + }; + + return this.sendRequest('create_user', data); + } + + deleteUser(name) { + const data = { + user: { + name: name + } + }; + + return this.sendRequest('delete_user', data); + } + + checkPassword(name, pass) { + const data = { + checkPass: { + name: name, + pass: pass + } + }; + + return this.sendRequest('check_password', data); + } + + checkPermission(name, permission) { + const data = { + permission: { + user: name, + name: permission + } + }; + + return this.sendRequest('check_permission', data); + } + + removePermission(name, permission) { + const data = { + permission: { + user: name, + name: permission + } + }; + + return this.sendRequest('remove_permission', data); + } + + getPermissionsRaw(name) { + const data = { + user: name + }; + + return this.sendRequest('get_permissions_raw', data); + } + + addPermission(name, permission) { + const data = { + permission: { + user: name, + name: permission + } + }; + + return this.sendRequest('add_permission', data); + } + + eval(func) { + const data = { + function: func + }; + + return this.sendRequest('eval', data); + } +} + +module.exports = LonaDB; diff --git a/JavaScript/README.md b/JavaScript/README.md new file mode 100644 index 0000000..aeb35a9 --- /dev/null +++ b/JavaScript/README.md @@ -0,0 +1,120 @@ +## Installation + +You can install the JavaScript-Client library using npm: + +```bash +npm install lonadb-client +``` + +## Usage + +To use the LonaDB Client library, follow these steps: + +1. Import the required modules and classes: + +```javascript +const LonaClient = require("lonadb-client"); +``` + +2. Create an instance of the `LonaDB-Client` class: + +```javascript +const client = new LonaClient(host, port, name, password); +``` + +Replace `host`, `port`, `name`, and `password` with the appropriate values for your LonaDB Server. + +3. Use the provided methods to interact with the server: + +```javascript +// Example: Get a list of tables +client.getTables() + .then(tables => { + console.log("List of tables:"); + console.log(tables); + }) + .catch(error => { + console.error("Error:", error); + }); +``` + +## Available Methods + +### `getTables(username)` + +Retrieves a list of tables available in the database. + +### `getTableData(table)` + +Retrieves data from a specified table. + +### `deleteTable(name)` + +Deletes a table by its name. + +### `createTable(name)` + +Creates a new table with the given name. + +### `set(table, name, value)` + +Sets a variable within a table to the specified value. + +### `delete(table, name)` + +Deletes a variable from a table. + +### `get(table, name)` + +Retrieves the value of a variable from a table. + +### `getUsers()` + +Retrieves a list of users in the database. + +### `createUser(name, password)` + +Creates a new user with the given name and password. + +### `deleteUser(name)` + +Deletes a user by their name. + +### `checkPassword(name, password)` + +Checks if the provided password is correct for a given user. + +### `checkPermission(user, permission)` + +Checks if a user has a specific permission. + +### `removePermission(user, permission)` + +Removes a permission from a user. + +### `getPermissionsRaw(name)` + +Retrieves the raw permission data for a user. + +### `addPermission(user, permission)` + +Adds a permission to a user. + +### `createFunction(name, content)` + +Create a function which can be executed whenever you want. Just like eval. +Content = string of PHP code + +### `executeFunction(name)` + +Executes the function + +### `eval(function)` + +Runs the function (must be a string of PHP code)
+Example: "if($abc === 1234) return 'wtf';" +Response: {"success": true, "response": "wtf", "process": processID} + +## License + +This project is licensed under the GNU Affero General Public License version 3 (GNU AGPL-3.0) \ No newline at end of file diff --git a/JavaScript/package-lock.json b/JavaScript/package-lock.json new file mode 100644 index 0000000..7466789 --- /dev/null +++ b/JavaScript/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "lonadb-client", + "version": "3.4.5", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "lonadb-client", + "version": "3.4.5", + "license": "AGPL-3.0", + "dependencies": { + "net": "^1.0.2" + } + }, + "node_modules/net": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", + "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" + } + }, + "dependencies": { + "net": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", + "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" + } + } +} diff --git a/JavaScript/package.json b/JavaScript/package.json new file mode 100644 index 0000000..ef8fd47 --- /dev/null +++ b/JavaScript/package.json @@ -0,0 +1,25 @@ +{ + "name": "lonadb-client", + "version": "4.5.1", + "description": "A client for the LonaDB Prototype", + "main": "Client.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/LonaDB/JavaScript-Client" + }, + "keywords": [ + "database", + "lonadb", + "json", + "variable", + "variables" + ], + "author": "Collin Buchkamer", + "license": "AGPL-3.0", + "dependencies": { + "net": "^1.0.2" + } +} diff --git a/PHP/Client.php b/PHP/Client.php new file mode 100644 index 0000000..69bb2c3 --- /dev/null +++ b/PHP/Client.php @@ -0,0 +1,244 @@ +host = $host; + $this->port = $port; + $this->name = $name; + $this->password = $password; + } + + private function makeid($length) { + $result = ""; + $characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; + $counter = 0; + + while ($counter < $length) { + $result .= $characters[mt_rand(0, strlen($characters) - 1)]; + $counter += 1; + } + + return $result; + } + + private function encryptPassword($password, $key) { + $keyBuffer = hash('sha256', $key, true); + + $iv = openssl_random_pseudo_bytes(16); + + $encrypted = openssl_encrypt($password, 'aes-256-cbc', $keyBuffer, OPENSSL_RAW_DATA, $iv); + + $encryptedString = bin2hex($iv) . ':' . bin2hex($encrypted); + + return $encryptedString; + } + + private function sendRequest($action, $data) { + $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($socket === false) { + return ["err" => socket_strerror(socket_last_error())]; + } + + $result = socket_connect($socket, $this->host, $this->port); + if ($result === false) { + return ["err" => socket_strerror(socket_last_error($socket))]; + } + + $processID = $this->makeid(5); + + $encryptedPassword = $this->encryptPassword($this->password, $processID); + + $request = json_encode([ + "action" => $action, + "login" => [ + "name" => $this->name, + "password" => $encryptedPassword + ], + "process" => $processID + ] + $data); + + socket_write($socket, $request, strlen($request)); + + $response = socket_read($socket, 2048); + socket_close($socket); + + return json_decode($response, true); + } + + public function createFunction($name, $content) { + $data = [ + "function" => [ + "name" => $name, + "content" => $content + ] + ]; + + return $this->sendRequest("add_function", $data); + } + + public function executeFunction($name) { + $data = [ + "name" => $name + ]; + + return $this->sendRequest("execute_function", $data); + } + + public function getTables($user) { + $data = [ + "user" => $user + ]; + + return $this->sendRequest("get_tables", $data); + } + + public function getTableData($table) { + $data = [ + "table" => $table + ]; + + return $this->sendRequest("get_table_data", $data); + } + + public function deleteTable($table) { + $data = [ + "table" => ["name" => $table] + ]; + + return $this->sendRequest("delete_table", $data); + } + + public function createTable($table) { + $data = [ + "table" => ["name" => $table] + ]; + + return $this->sendRequest("create_table", $data); + } + + public function set($table, $name, $value) { + $data = [ + "table" => ["name" => $table], + "variable" => [ + "name" => $name, + "value" => $value + ] + ]; + + return $this->sendRequest("set_variable", $data); + } + + public function delete($table, $name){ + $data = [ + "table" => ["name" => $table], + "variable" => ["name" => $name] + ]; + + return $this->sendRequest("remove_variable", $data); + } + + public function get($table, $name){ + $data = [ + "table" => ["name" => $table], + "variable" => [ + "name" => $name + ] + ]; + + return $this->sendRequest("get_variable", $data); + } + + public function getUsers(){ + $data = []; + + return $this->sendRequest("get_users", $data); + } + + public function createUser($name, $pass){ + $data = [ + "user" => [ + "name" => $name, + "password" => $pass + ] + ]; + + return $this->sendRequest("create_user", $data); + } + + public function deleteUser($name){ + $data = [ + "user" => [ + "name" => $name + ] + ]; + + return $this->sendRequest("delete_user", $data); + } + + public function checkPassword($name, $pass){ + $data = [ + "checkPass" => [ + "name" => $name, + "pass" => $pass + ] + ]; + + return $this->sendRequest("check_password", $data); + } + + public function checkPermission($name, $permission){ + $data = [ + "permission" => [ + "user" => $name, + "name" => $permission + ] + ]; + + return $this->sendRequest("check_permission", $data); + } + + public function removePermission($name, $permission){ + $data = [ + "permission" => [ + "user" => $name, + "name" => $permission + ] + ]; + + return $this->sendRequest("remove_permission", $data); + } + + public function getPermissionsRaw($name){ + $data = [ + "user" => $name + ]; + + return $this->sendRequest("get_permissions_raw", $data); + } + + public function addPermission($name){ + $data = [ + "permission" => [ + "user" => $name, + "name" => $permission + ] + ]; + + return $this->sendRequest("add_permission", $data); + } + + public function eval($func) { + $data = [ + "function" => $func + ]; + + return $this->sendRequest("eval", $data); + } +} + +?> \ No newline at end of file diff --git a/PHP/README.md b/PHP/README.md new file mode 100644 index 0000000..48c26c9 --- /dev/null +++ b/PHP/README.md @@ -0,0 +1,112 @@ +## Installation + +You can use the LonaDB PHP Client by including it in your project. Simply download the `LonaDB.php` file and include it in your PHP project. + +## Usage + +To use the `LonaDB` PHP Client, follow these steps: + +1. Include the `LonaDB` class in your PHP file: + +```php +require_once('path/to/LonaDB.php'); +``` + +2. Create an instance of the `LonaDB` class by providing the required connection details: + +```php +$client = new LonaDB($host, $port, $name, $password); +``` + +Replace `$host`, `$port`, `$name`, and `$password` with the appropriate values for your LonaDB Server. + +3. Use the provided methods to interact with the server: + +```php +// Example: Get a list of tables +$tables = $client->getTables("username"); + +// Display the list of tables +print_r($tables); +``` + +## Available Methods + +### `getTables(username)` + +Retrieves a list of tables available in the database. + +### `getTableData(table)` + +Retrieves data from a specified table. + +### `deleteTable(name)` + +Deletes a table by its name. + +### `createTable(name)` + +Creates a new table with the given name. + +### `set(table, name, value)` + +Sets a variable within a table to the specified value. + +### `delete(table, name)` + +Deletes a variable from a table. + +### `get(table, name)` + +Retrieves the value of a variable from a table. + +### `getUsers()` + +Retrieves a list of users in the database. + +### `createUser(name, password)` + +Creates a new user with the given name and password. + +### `deleteUser(name)` + +Deletes a user by their name. + +### `checkPassword(name, password)` + +Checks if the provided password is correct for a given user. + +### `checkPermission(user, permission)` + +Checks if a user has a specific permission. + +### `removePermission(user, permission)` + +Removes a permission from a user. + +### `getPermissionsRaw(name)` + +Retrieves the raw permission data for a user. + +### `addPermission(user, permission)` + +Adds a permission to a user. + +### `createFunction(name, content)` + +Create a function which can be executed whenever you want. Just like eval. +Content = string of PHP code + +### `executeFunction(name)` + +Executes the function + +### `eval(function)` + +Runs the function (must be a string of PHP code)
+Example: "if($abc === 1234) return 'wtf';" +Response: {"success": true, "response": "wtf", "process": processID} + +## License + +This project is licensed under the GNU Affero General Public License version 3 (GNU AGPL-3.0). \ No newline at end of file diff --git a/Python/.gitignore b/Python/.gitignore new file mode 100644 index 0000000..7dbb66e --- /dev/null +++ b/Python/.gitignore @@ -0,0 +1,4 @@ +venv +dist +build +lonadb_client.egg-info \ No newline at end of file diff --git a/Python/README.md b/Python/README.md new file mode 100644 index 0000000..29f272e --- /dev/null +++ b/Python/README.md @@ -0,0 +1,116 @@ +## Installation + +You can install the LonaDB Python Client via pip: + +```bash +pip install lonadb-client +``` + +## Usage + +To use the `LonaDB` Python Client, follow these steps: + +1. Import the `LonaDB` class into your Python script: + +```python +from lonadb_client import LonaDB +``` + +2. Create an instance of the `LonaDB` class by providing the required connection details: + +```python +client = LonaDB(host, port, name, password) +``` + +Replace `host`, `port`, `name`, and `password` with the appropriate values for your LonaDB server. + +3. Use the provided methods to interact with the server: + +```python +# Example: Get a list of tables +tables = client.get_tables("username"); + +# Display the list of tables +print(tables) +``` + +## Available Methods + +### `get_tables(user)` + +Retrieves a list of tables available in the database. + +### `get_table_data(table)` + +Retrieves data from a specified table. + +### `delete_table(table)` + +Deletes a table by its name. + +### `create_table(table)` + +Creates a new table with the given name. + +### `set_variable(table, name, value)` + +Sets a variable within a table to the specified value. + +### `remove_variable(table, name)` + +Deletes a variable from a table. + +### `get_variable(table, name)` + +Retrieves the value of a variable from a table. + +### `get_users()` + +Retrieves a list of users in the database. + +### `create_user(name, password)` + +Creates a new user with the given name and password. + +### `delete_user(name)` + +Deletes a user by their name. + +### `check_password(name, password)` + +Checks if the provided password is correct for a given user. + +### `check_permission(name, permission)` + +Checks if a user has a specific permission. + +### `remove_permission(name, permission)` + +Removes a permission from a user. + +### `get_permissions_raw(name)` + +Retrieves the raw permission data for a user. + +### `add_permission(name, permission)` + +Adds a permission to a user. + +### `create_function(name, content)` + +Create a function which can be executed whenever you want. Just like eval. +Content = string of PHP code + +### `execute_function(name)` + +Executes the function + +### `eval(func)` + +Runs the function (must be a string of PHP code) +Example: "if ($abc == 1234) return 'wtf';" +Response: {"success": True, "response": "wtf", "process": processID} + +## License + +This project is licensed under the GNU Affero General Public License version 3 (GNU AGPL-3.0). \ No newline at end of file diff --git a/Python/lonadb_client/__init__.py b/Python/lonadb_client/__init__.py new file mode 100644 index 0000000..a1c868f --- /dev/null +++ b/Python/lonadb_client/__init__.py @@ -0,0 +1,3 @@ +from .lonadb_client import LonaDB + +__all__ = ["LonaDB"] diff --git a/Python/lonadb_client/lonadb_client.py b/Python/lonadb_client/lonadb_client.py new file mode 100644 index 0000000..0ffdae2 --- /dev/null +++ b/Python/lonadb_client/lonadb_client.py @@ -0,0 +1,146 @@ +import json +import socket + +class LonaDB: + def __init__(self, host, port, name, password): + self.host = host + self.port = port + self.name = name + self.password = password + + def make_id(self, length): + import random + import string + return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length)) + + def send_request(self, action, data): + process_id = self.make_id(5) + request = json.dumps({ + 'action': action, + 'login': { + 'name': self.name, + 'password': self.password + }, + 'process': process_id, + **data + }) + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((self.host, self.port)) + s.sendall(request.encode()) + response = s.recv(4096).decode() + return json.loads(response) + + def create_function(self, name, content): + data = { + 'function': { + 'name': name, + 'content': content + } + } + return self.send_request('add_function', data) + + def execute_function(self, name): + data = {'name': name} + return self.send_request('execute_function', data) + + def get_tables(self, user): + data = {'user': user} + return self.send_request('get_tables', data) + + def get_table_data(self, table): + data = {'table': table} + return self.send_request('get_table_data', data) + + def delete_table(self, table): + data = {'table': {'name': table}} + return self.send_request('delete_table', data) + + def create_table(self, table): + data = {'table': {'name': table}} + return self.send_request('create_table', data) + + def set_variable(self, table, name, value): + data = { + 'table': {'name': table}, + 'variable': { + 'name': name, + 'value': value + } + } + return self.send_request('set_variable', data) + + def remove_variable(self, table, name): + data = { + 'table': {'name': table}, + 'variable': {'name': name} + } + return self.send_request('remove_variable', data) + + def get_variable(self, table, name): + data = { + 'table': {'name': table}, + 'variable': {'name': name} + } + return self.send_request('get_variable', data) + + def get_users(self): + data = {} + return self.send_request('get_users', data) + + def create_user(self, name, password): + data = { + 'user': { + 'name': name, + 'password': password + } + } + return self.send_request('create_user', data) + + def delete_user(self, name): + data = {'user': {'name': name}} + return self.send_request('delete_user', data) + + def check_password(self, name, password): + data = { + 'checkPass': { + 'name': name, + 'pass': password + } + } + return self.send_request('check_password', data) + + def check_permission(self, name, permission): + data = { + 'permission': { + 'user': name, + 'name': permission + } + } + return self.send_request('check_permission', data) + + def remove_permission(self, name, permission): + data = { + 'permission': { + 'user': name, + 'name': permission + } + } + return self.send_request('remove_permission', data) + + def get_permissions_raw(self, name): + data = {'user': name} + return self.send_request('get_permissions_raw', data) + + def add_permission(self, name, permission): + data = { + 'permission': { + 'user': name, + 'name': permission + } + } + return self.send_request('add_permission', data) + + def eval(self, func): + data = {'function': func} + return self.send_request('eval', data) \ No newline at end of file diff --git a/Python/requirements.txt b/Python/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/Python/setup.py b/Python/setup.py new file mode 100644 index 0000000..9aba59a --- /dev/null +++ b/Python/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup + +from pathlib import Path +this_directory = Path(__file__).parent +long_description = (this_directory / "README.md").read_text() + +setup( + name="lonadb-client", + version="2.1", + author="Collin Buchkamer", + author_email="collin@lona-development.org", + description="A client library for interacting with LonaDB server", + url="https://github.com/LonaDB/Clients", + packages=["lonadb_client"], + long_description=long_description, + long_description_content_type='text/markdown', + license="MIT", + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + ], + keywords="lonadb client database", + platforms="any", +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..e59a2c8 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Clients +To use LonaDB for your own project, you need to use one of the clients. + +[PHP](https://docs.lona-development.org/guide/php.html)
+[JavaScript](https://docs.lona-development.org/guide/javascript.html)
+[Python](https://docs.lona-development.org/guide/python.html) + +We are interested in making LonaDB available in more languages but we are a small team of 4 developers.
+Do you want to help us? Join our Discord Server! \ No newline at end of file