98 lines
3.5 KiB
C++
98 lines
3.5 KiB
C++
#include "database_manager.h"
|
|
#include <memory>
|
|
#include "vfs.h"
|
|
|
|
DatabaseManager::DatabaseManager(const std::string& db_path) :
|
|
_db(db_path) {
|
|
_player_repository = std::make_unique<PlayerRepository>(_db);
|
|
_machine_repository = std::make_unique<MachineRepository>(_db);
|
|
_service_repository = std::make_unique<ServiceRepository>(_db);
|
|
_vfs_repository = std::make_unique<VFSRepository>(_db);
|
|
|
|
_db << "CREATE TABLE IF NOT EXISTS players("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
"username TEXT NOT NULL UNIQUE,"
|
|
"password TEXT NOT NULL,"
|
|
"hostname TEXT NOT NULL,"
|
|
"home_machine_id INTEGER"
|
|
");";
|
|
|
|
_db << "CREATE TABLE IF NOT EXISTS machines ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
"owner_id INTEGER,"
|
|
"hostname TEXT NOT NULL,"
|
|
"ip_address TEXT NOT NULL UNIQUE"
|
|
");";
|
|
|
|
_db << "CREATE TABLE IF NOT EXISTS vfs_nodes ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
"machine_id INTEGER NOT NULL,"
|
|
"parent_id INTEGER,"
|
|
"name TEXT NOT NULL,"
|
|
"type INTEGER NOT NULL,"
|
|
"content TEXT,"
|
|
"owner_id INTEGER NOT NULL,"
|
|
"group_id INTEGER NOT NULL,"
|
|
"permissions INTEGER NOT NULL"
|
|
");";
|
|
_db << "CREATE TABLE IF NOT EXISTS services ("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
"machine_id INTEGER NOT NULL,"
|
|
"port INTEGER NOT NULL,"
|
|
"name TEXT NOT NULL"
|
|
");";
|
|
}
|
|
|
|
DatabaseManager::~DatabaseManager(void) {
|
|
/* db is auto closed when _db goes out of scope. */
|
|
}
|
|
|
|
bool DatabaseManager::create_player(const std::string& username, const std::string& password,
|
|
const std::string& hostname, vfs_node* vfs_template) {
|
|
long long player_id = 0;
|
|
long long machine_id = 0;
|
|
|
|
try {
|
|
_db << "BEGIN;";
|
|
|
|
player_id = _player_repository->create(username, password, hostname);
|
|
|
|
/* Create the home machine. */
|
|
/* TODO: Implement real IP allication. */
|
|
std::string ip_address = "192.168.1." + std::to_string(player_id);
|
|
machine_id = _machine_repository->create(player_id, hostname, ip_address);
|
|
|
|
_player_repository->set_home_machine_id(player_id, machine_id);
|
|
|
|
/* Create the root dir for the new machine's VFS. */
|
|
long long root_id = _vfs_repository->create_node(machine_id, nullptr, "/", DIR_NODE,
|
|
"", player_id, player_id, 0755);
|
|
|
|
/* Create default subdirs. */
|
|
_vfs_repository->create_node(machine_id, &root_id, "home", DIR_NODE,
|
|
"", player_id, player_id, 0755);
|
|
_vfs_repository->create_node(machine_id, &root_id, "etc", DIR_NODE,
|
|
"", player_id, player_id, 0755);
|
|
|
|
/* Create /bin and get it's ID */
|
|
long long bin_id = _vfs_repository->create_node(machine_id, &root_id, "bin", DIR_NODE,
|
|
"", player_id, player_id, 0755);
|
|
|
|
/* Copy scripts from template into new machine's /bin */
|
|
vfs_node* template_bin = vfs_template->children["bin"];
|
|
for(auto const& [name, node] : template_bin->children) {
|
|
_vfs_repository->create_node(machine_id, &bin_id, name, node->type, node->content,
|
|
player_id, player_id, 0755);
|
|
}
|
|
|
|
/* Add default SSH service. */
|
|
_service_repository->create(machine_id, 22, "SSH");
|
|
|
|
_db << "COMMIT";
|
|
} catch(const std::exception& e) {
|
|
_db << "ROLLBACK;"; /* Ensure atomicity. */
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|