Add SQL schema, CLI commands, and initialization logic
This commit is contained in:
parent
bc6e814c42
commit
ff1363c63f
12 changed files with 327 additions and 1 deletions
3
.idea/sqldialects.xml
generated
3
.idea/sqldialects.xml
generated
|
@ -1,6 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="SqlDialectMappings">
|
<component name="SqlDialectMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/password_authentication.sql" dialect="MariaDB" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/registered_peers.sql" dialect="MariaDB" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/sessions.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/SessionManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/SessionManager.php" dialect="MariaDB" />
|
||||||
<file url="file:///var/ncc/packages/net.nosial.socialbox=1.0.0/bin/src/Socialbox/Managers/SessionManager.php" dialect="MariaDB" />
|
<file url="file:///var/ncc/packages/net.nosial.socialbox=1.0.0/bin/src/Socialbox/Managers/SessionManager.php" dialect="MariaDB" />
|
||||||
</component>
|
</component>
|
||||||
|
|
1
.idea/webResources.xml
generated
1
.idea/webResources.xml
generated
|
@ -6,6 +6,7 @@
|
||||||
<entryData>
|
<entryData>
|
||||||
<resourceRoots>
|
<resourceRoots>
|
||||||
<path value="file://$PROJECT_DIR$/examples" />
|
<path value="file://$PROJECT_DIR$/examples" />
|
||||||
|
<path value="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources" />
|
||||||
</resourceRoots>
|
</resourceRoots>
|
||||||
</entryData>
|
</entryData>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
85
src/Socialbox/Classes/CliCommands/InitializeCommand.php
Normal file
85
src/Socialbox/Classes/CliCommands/InitializeCommand.php
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Classes\CliCommands;
|
||||||
|
|
||||||
|
use LogLib\Log;
|
||||||
|
use PDOException;
|
||||||
|
use Socialbox\Classes\Configuration;
|
||||||
|
use Socialbox\Classes\Database;
|
||||||
|
use Socialbox\Classes\Resources;
|
||||||
|
use Socialbox\Enums\DatabaseObjects;
|
||||||
|
use Socialbox\Interfaces\CliCommandInterface;
|
||||||
|
|
||||||
|
class InitializeCommand implements CliCommandInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Executes the command with the given arguments.
|
||||||
|
*
|
||||||
|
* @param array $args An array of arguments to be processed.
|
||||||
|
* @return int The result of the execution as an integer.
|
||||||
|
*/
|
||||||
|
public static function execute(array $args): int
|
||||||
|
{
|
||||||
|
if(Configuration::getConfiguration()['instance']['enabled'] === false && !isset($args['force']))
|
||||||
|
{
|
||||||
|
Log::info('net.nosial.socialbox', 'Socialbox is disabled. Use --force to initialize the instance or set `instance.enabled` to True in the configuration');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Initializing Socialbox...\n");
|
||||||
|
foreach(DatabaseObjects::casesOrdered() as $object)
|
||||||
|
{
|
||||||
|
Log::verbose('net.nosial.socialbox', "Initializing database object {$object->value}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Database::getConnection()->exec(file_get_contents(Resources::getDatabaseResource($object)));
|
||||||
|
}
|
||||||
|
catch (PDOException $e)
|
||||||
|
{
|
||||||
|
// Check if the error code is for "table already exists"
|
||||||
|
if ($e->getCode() === '42S01')
|
||||||
|
{
|
||||||
|
Log::warning('net.nosial.socialbox', "Database object {$object->value} already exists, skipping...");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::error('net.nosial.socialbox', "Failed to initialize database object {$object->value}: {$e->getMessage()}", $e);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(\Exception $e)
|
||||||
|
{
|
||||||
|
Log::error('net.nosial.socialbox', "Failed to initialize database object {$object->value}: {$e->getMessage()}", $e);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('net.nosial.socialbox', 'Socialbox has been initialized successfully');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the help message for the command.
|
||||||
|
*
|
||||||
|
* @return string The help message.
|
||||||
|
*/
|
||||||
|
public static function getHelpMessage(): string
|
||||||
|
{
|
||||||
|
return "Initialize Command - Initializes Socialbox for first-runs\n" .
|
||||||
|
"Usage: socialbox init [arguments]\n\n" .
|
||||||
|
"Arguments:\n" .
|
||||||
|
" --force - Forces the initialization process to run even the instance is disabled\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a short help message for the command.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getShortHelpMessage(): string
|
||||||
|
{
|
||||||
|
return "Initializes Socialbox for first-runs";
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,9 @@ class Configuration
|
||||||
{
|
{
|
||||||
$config = new \ConfigLib\Configuration('net.nosial.socialbox');
|
$config = new \ConfigLib\Configuration('net.nosial.socialbox');
|
||||||
|
|
||||||
|
// False by default, requires the user to enable it.
|
||||||
|
$config->setDefault('instance.enabled', false);
|
||||||
|
|
||||||
$config->setDefault('database.host', '127.0.0.1');
|
$config->setDefault('database.host', '127.0.0.1');
|
||||||
$config->setDefault('database.port', 3306);
|
$config->setDefault('database.port', 3306);
|
||||||
$config->setDefault('database.username', 'root');
|
$config->setDefault('database.username', 'root');
|
||||||
|
|
15
src/Socialbox/Classes/Resources.php
Normal file
15
src/Socialbox/Classes/Resources.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Classes;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Socialbox\Enums\DatabaseObjects;
|
||||||
|
|
||||||
|
class Resources
|
||||||
|
{
|
||||||
|
public static function getDatabaseResource(DatabaseObjects $object): string
|
||||||
|
{
|
||||||
|
$tables_directory = __DIR__ . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'database';
|
||||||
|
return $tables_directory . DIRECTORY_SEPARATOR . $object->value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
create table password_authentication
|
||||||
|
(
|
||||||
|
peer_uuid varchar(36) not null comment 'The Primary unique Index for the peer UUID'
|
||||||
|
primary key,
|
||||||
|
value varchar(128) not null comment 'The hash value of the pasword',
|
||||||
|
updated timestamp default current_timestamp() not null comment 'The Timestamp for when this record was last updated',
|
||||||
|
constraint password_authentication_peer_uuid_uindex
|
||||||
|
unique (peer_uuid) comment 'The Primary unique Index for the peer UUID',
|
||||||
|
constraint password_authentication_registered_peers_uuid_fk
|
||||||
|
foreign key (peer_uuid) references registered_peers (uuid)
|
||||||
|
on update cascade on delete cascade
|
||||||
|
)
|
||||||
|
comment 'Table for housing password authentications associated with peers';
|
||||||
|
|
||||||
|
create index password_authentication_updated_index
|
||||||
|
on password_authentication (updated)
|
||||||
|
comment 'The Indefor the updated timestamp';
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
create table registered_peers
|
||||||
|
(
|
||||||
|
uuid varchar(36) default uuid() not null comment 'The Primary index for the peer uuid'
|
||||||
|
primary key,
|
||||||
|
username varchar(255) not null comment 'The Unique username associated with the peer',
|
||||||
|
flags text null comment 'Comma seprted flags associated with the peer',
|
||||||
|
registered timestamp default current_timestamp() not null comment 'The Timestamp for when the peer was registered on the network',
|
||||||
|
constraint registered_peers_pk_2
|
||||||
|
unique (username) comment 'The unique username for the peer',
|
||||||
|
constraint registered_peers_username_uindex
|
||||||
|
unique (username) comment 'The unique username for the peer',
|
||||||
|
constraint registered_peers_uuid_uindex
|
||||||
|
unique (uuid) comment 'The Primary index for the peer uuid'
|
||||||
|
)
|
||||||
|
comment 'Table for housing registered peers under this network';
|
||||||
|
|
||||||
|
create index registered_peers_registered_index
|
||||||
|
on registered_peers (registered)
|
||||||
|
comment 'The Index for the reigstered column of the peer';
|
||||||
|
|
24
src/Socialbox/Classes/Resources/database/sessions.sql
Normal file
24
src/Socialbox/Classes/Resources/database/sessions.sql
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
create table sessions
|
||||||
|
(
|
||||||
|
uuid varchar(36) default uuid() not null comment 'The Unique Primary index for the session UUID'
|
||||||
|
primary key,
|
||||||
|
authenticated_peer_uuid varchar(36) null comment 'The peer the session is authenticated as, null if the session isn''t authenticated',
|
||||||
|
public_key blob not null comment 'The client''s public key provided when creating the session',
|
||||||
|
state enum ('ACTIVE', 'EXPIRED', 'CLOSED') default 'ACTIVE' not null comment 'The status of the session',
|
||||||
|
created timestamp default current_timestamp() not null comment 'The Timestamp for when the session was last created',
|
||||||
|
last_request timestamp null comment 'The Timestamp for when the last request was made using this session',
|
||||||
|
constraint sessions_uuid_uindex
|
||||||
|
unique (uuid) comment 'The Unique Primary index for the session UUID',
|
||||||
|
constraint sessions_registered_peers_uuid_fk
|
||||||
|
foreign key (authenticated_peer_uuid) references registered_peers (uuid)
|
||||||
|
on update cascade on delete cascade
|
||||||
|
);
|
||||||
|
|
||||||
|
create index sessions_authenticated_peer_index
|
||||||
|
on sessions (authenticated_peer_uuid)
|
||||||
|
comment 'The Index for the authenticated peer column';
|
||||||
|
|
||||||
|
create index sessions_created_index
|
||||||
|
on sessions (created)
|
||||||
|
comment 'The Index for the created column of the session';
|
||||||
|
|
40
src/Socialbox/Enums/CliCommands.php
Normal file
40
src/Socialbox/Enums/CliCommands.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Enums;
|
||||||
|
|
||||||
|
use Socialbox\Classes\CliCommands\HelpCommand;
|
||||||
|
use Socialbox\Classes\CliCommands\InitializeCommand;
|
||||||
|
|
||||||
|
enum CliCommands : string
|
||||||
|
{
|
||||||
|
case INITIALIZE = 'init';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the command execution, returns the exit code.
|
||||||
|
*
|
||||||
|
* @param array $args An array of arguments to be processed.
|
||||||
|
* @return int The result of the execution as an integer.
|
||||||
|
*/
|
||||||
|
public function handle(array $args): int
|
||||||
|
{
|
||||||
|
return match ($this)
|
||||||
|
{
|
||||||
|
self::INITIALIZE => InitializeCommand::execute($args),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public function getHelpMessage(): string
|
||||||
|
{
|
||||||
|
return match ($this)
|
||||||
|
{
|
||||||
|
self::INITIALIZE => InitializeCommand::getHelpMessage()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortHelpMessage(): string
|
||||||
|
{
|
||||||
|
return match ($this)
|
||||||
|
{
|
||||||
|
self::INITIALIZE => InitializeCommand::getShortHelpMessage()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
36
src/Socialbox/Enums/DatabaseObjects.php
Normal file
36
src/Socialbox/Enums/DatabaseObjects.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Enums;
|
||||||
|
|
||||||
|
enum DatabaseObjects : string
|
||||||
|
{
|
||||||
|
case PASSWORD_AUTHENTICATION = 'password_authentication.sql';
|
||||||
|
case REGISTERED_PEERS = 'registered_peers.sql';
|
||||||
|
case SESSIONS = 'sessions.sql';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the priority of the database object
|
||||||
|
*
|
||||||
|
* @return int The priority of the database object
|
||||||
|
*/
|
||||||
|
public function getPriority(): int
|
||||||
|
{
|
||||||
|
return match ($this)
|
||||||
|
{
|
||||||
|
self::REGISTERED_PEERS => 1,
|
||||||
|
self::PASSWORD_AUTHENTICATION, self::SESSIONS => 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of cases ordered by their priority.
|
||||||
|
*
|
||||||
|
* @return array The array of cases sorted by their priority.
|
||||||
|
*/
|
||||||
|
public static function casesOrdered(): array
|
||||||
|
{
|
||||||
|
$cases = self::cases();
|
||||||
|
usort($cases, fn($a, $b) => $a->getPriority() <=> $b->getPriority());
|
||||||
|
return $cases;
|
||||||
|
}
|
||||||
|
}
|
28
src/Socialbox/Interfaces/CliCommandInterface.php
Normal file
28
src/Socialbox/Interfaces/CliCommandInterface.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Interfaces;
|
||||||
|
|
||||||
|
interface CliCommandInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Executes the given set of arguments.
|
||||||
|
*
|
||||||
|
* @param array $args An array of arguments to be processed.
|
||||||
|
* @return int The result of the execution as an integer.
|
||||||
|
*/
|
||||||
|
public static function execute(array $args): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the help message for the command.
|
||||||
|
*
|
||||||
|
* @return string The help message for the command.
|
||||||
|
*/
|
||||||
|
public static function getHelpMessage(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the short help message for the command.
|
||||||
|
*
|
||||||
|
* @return string The short help message for the command.
|
||||||
|
*/
|
||||||
|
public static function getShortHelpMessage(): string;
|
||||||
|
}
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
namespace Socialbox;
|
namespace Socialbox;
|
||||||
|
|
||||||
|
use OptsLib\Parse;
|
||||||
|
use Socialbox\Enums\CliCommands;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +15,57 @@
|
||||||
*/
|
*/
|
||||||
public static function main(array $args): int
|
public static function main(array $args): int
|
||||||
{
|
{
|
||||||
print("Hello World from net.nosial.socialbox!" . PHP_EOL);
|
// Parse the arguments into a more usable array format
|
||||||
|
$args = Parse::parseArgument($args);
|
||||||
|
|
||||||
|
if(isset($args['help']))
|
||||||
|
{
|
||||||
|
if($args['help'] === true)
|
||||||
|
{
|
||||||
|
return self::displayHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
$command = CliCommands::tryFrom($args['help']);
|
||||||
|
|
||||||
|
if($command === null)
|
||||||
|
{
|
||||||
|
print(sprintf("Unknown command '%s'\n", $args['help']));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
print($command->getHelpMessage());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($args[CliCommands::INITIALIZE->value]))
|
||||||
|
{
|
||||||
|
return CliCommands::INITIALIZE->handle($args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::displayHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the help message for the Socialbox CLI Management Interface.
|
||||||
|
*
|
||||||
|
* This method prints out the usage instructions and a list of available commands.
|
||||||
|
*
|
||||||
|
* @return int Returns 0 upon successful display of the help message.
|
||||||
|
*/
|
||||||
|
private static function displayHelp(): int
|
||||||
|
{
|
||||||
|
print("Socialbox - CLI Management Interface\n");
|
||||||
|
print("Usage: socialbox [command] [arguments]\n\n");
|
||||||
|
print("Commands:\n");
|
||||||
|
print(" help - Displays this help message.\n");
|
||||||
|
|
||||||
|
foreach(CliCommands::cases() as $command)
|
||||||
|
{
|
||||||
|
print(sprintf(" %s - %s\n", $command->value, $command->getShortHelpMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Use 'socialbox --help=[command]' for more information about a command.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue