diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index a012e6b..1bb0402 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -1,6 +1,9 @@ + + + diff --git a/.idea/webResources.xml b/.idea/webResources.xml index 77233d9..38d7e3c 100644 --- a/.idea/webResources.xml +++ b/.idea/webResources.xml @@ -6,6 +6,7 @@ + diff --git a/src/Socialbox/Classes/CliCommands/InitializeCommand.php b/src/Socialbox/Classes/CliCommands/InitializeCommand.php new file mode 100644 index 0000000..bc74fb1 --- /dev/null +++ b/src/Socialbox/Classes/CliCommands/InitializeCommand.php @@ -0,0 +1,85 @@ +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"; + } +} \ No newline at end of file diff --git a/src/Socialbox/Classes/Configuration.php b/src/Socialbox/Classes/Configuration.php index dd2bc95..5acf5bd 100644 --- a/src/Socialbox/Classes/Configuration.php +++ b/src/Socialbox/Classes/Configuration.php @@ -12,6 +12,9 @@ class Configuration { $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.port', 3306); $config->setDefault('database.username', 'root'); diff --git a/src/Socialbox/Classes/Resources.php b/src/Socialbox/Classes/Resources.php new file mode 100644 index 0000000..c932bab --- /dev/null +++ b/src/Socialbox/Classes/Resources.php @@ -0,0 +1,15 @@ +value; + } +} \ No newline at end of file diff --git a/src/Socialbox/Classes/Resources/database/password_authentication.sql b/src/Socialbox/Classes/Resources/database/password_authentication.sql new file mode 100644 index 0000000..90bc79a --- /dev/null +++ b/src/Socialbox/Classes/Resources/database/password_authentication.sql @@ -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'; + diff --git a/src/Socialbox/Classes/Resources/database/registered_peers.sql b/src/Socialbox/Classes/Resources/database/registered_peers.sql new file mode 100644 index 0000000..59e1914 --- /dev/null +++ b/src/Socialbox/Classes/Resources/database/registered_peers.sql @@ -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'; + diff --git a/src/Socialbox/Classes/Resources/database/sessions.sql b/src/Socialbox/Classes/Resources/database/sessions.sql new file mode 100644 index 0000000..6c247b4 --- /dev/null +++ b/src/Socialbox/Classes/Resources/database/sessions.sql @@ -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'; + diff --git a/src/Socialbox/Enums/CliCommands.php b/src/Socialbox/Enums/CliCommands.php new file mode 100644 index 0000000..d160006 --- /dev/null +++ b/src/Socialbox/Enums/CliCommands.php @@ -0,0 +1,40 @@ + 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() + }; + } +} diff --git a/src/Socialbox/Enums/DatabaseObjects.php b/src/Socialbox/Enums/DatabaseObjects.php new file mode 100644 index 0000000..5ca0b51 --- /dev/null +++ b/src/Socialbox/Enums/DatabaseObjects.php @@ -0,0 +1,36 @@ + 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; + } +} diff --git a/src/Socialbox/Interfaces/CliCommandInterface.php b/src/Socialbox/Interfaces/CliCommandInterface.php new file mode 100644 index 0000000..b89ed5c --- /dev/null +++ b/src/Socialbox/Interfaces/CliCommandInterface.php @@ -0,0 +1,28 @@ +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; } } \ No newline at end of file